La ubicación de la palabra clave where en la consulta de conexión SQL

Últimamente he estado ocupado y no tengo mucho tiempo para quedarme y escribir un blog. Por la noche, encontré un problema de SQL que encontré muy interesante, que puede ser útil para principiantes y novatos como yo, así que decidí compartirlo con todos.

Debido a que el autor es intrínsecamente torpe, no es riguroso en el pensamiento y realmente no es bueno para escribir declaraciones SQL, los maestros no se ríen, omita este artículo.


No introduciré mucho el fondo. Primero, cree una tabla e inserte los datos de prueba. Los campos tienen comentarios

--医生表
CREATE TABLE doctor
    (
      id INT IDENTITY(1, 1) , --ID 自增长
      docNumber NVARCHAR(50) NOT NULL , --医生编码
      NAME NVARCHAR(50) NOT NULL   --医生姓名
    )
go

--插入测试数据
INSERT  INTO doctor
VALUES  ( '007', 'Tom' )
INSERT  INTO doctor
VALUES  ( '008', 'John' )
INSERT  INTO doctor
VALUES  ( '009', 'Jim' )


--号源表(挂号表)
CREATE TABLE Nosource
    (
      id INT IDENTITY(1, 1) ,
      docNumber NVARCHAR(50) NOT NULL , --和医生表中的医生编码对应
      workTime DATETIME NOT NULL
    )

go
--插入测试数据
INSERT  INTO Nosource
VALUES  ( '007', '20120819' )
INSERT  INTO Nosource
VALUES  ( '007', '20120820' )
INSERT  INTO Nosource
VALUES  ( '007', '20120821' )
INSERT  INTO Nosource
VALUES  ( '008', '20120821' )

Una vez construida la tabla, los datos de prueba también son correctos. Comencemos a hablar de la demanda.

1. Averigüe la información relevante de cada médico y la cantidad de fuentes que posee ese médico.

Esto es demasiado simple, tal vez incluso los amigos que acaban de aprender helloWorld y un poco de lo básico de la base de datos sean una tontería seria y sincera. Pero el código todavía está escrito.

--简单的分组查询即可搞定
SELECT  COUNT(nos.id) AS PersonNumSounceCOUNT , --总数
        dct.ID AS docID ,
        dct.NAME ,
        dct.docNumber ,
        nos.workTime
FROM    doctor AS dct
        LEFT JOIN Nosource AS nos ON dct.docNumber = nos.docNumber
GROUP BY dct.ID ,
        dct.NAME ,
        dct.docNumber ,
        nos.workTime

Es realmente sencillo. Se puede hacer un grupo pequeño. ¿Qué más vendes?

Ahora que la demanda cambia, debe coincidir de acuerdo con las condiciones: el tiempo de trabajo de la tabla de origen de números requeridos es mayor que la fecha actual para que sea válida, de lo contrario no coincidirá.
Si la condición workTime no coincide con la del médico, el valor del campo PersonNumSounceCOUNT correspondiente debe ser 0; por ejemplo, si el médico Jim no tiene una fuente de números calificada y coincidente, el valor del campo PersonNumSounceCOUNT debe ser 0. Mirando hacia el cielo 40 grados, piense en la capacidad de filtrar con la palabra clave where, y luego consultarlo todo a la vez. Intentalo.

SELECT  COUNT(nos.id) AS PersonNumSounceCOUNT , --总数
        dct.ID ,
        dct.NAME ,
        dct.docNumber ,
        nos.workTime
FROM    doctor AS dct
        LEFT JOIN Nosource AS nos ON dct.docNumber = nos.docNumber
WHERE   DATEDIFF(day, GETDATE(), nos.workTime) > 0
GROUP BY dct.ID ,
        dct.NAME ,
        dct.docNumber ,
        nos.workTime

Creo que alguien escribirá el código anterior. Pero después de ejecutar la consulta, descubrí que no cumplía con los requisitos. Incluso la información básica y los registros de tablas del Dr. Jim se han filtrado y desaparecido. ¿Qué pasa?

La razón es simple. Utilice la palabra clave "where" después de la consulta de conexión para filtrar los datos en el conjunto de resultados de la consulta de conexión. Debido a que las condiciones de la tabla de la derecha (tabla de origen numérico) no coinciden, los datos de la tabla de la izquierda (tabla de doctor) también se filtrarán.

Por lo tanto, se producirá el fenómeno anterior (la información y los registros del Dr. Jim desaparecieron). ¿Es posible averiguarlo todo a la vez? ¿Cómo lograrlo?


De hecho, la escritura correcta debería ser así:

SELECT  COUNT(nos.id) AS PersonNumSounceCOUNT , --总数
        dct.ID ,
        dct.NAME ,
        dct.docNumber ,
        nos.workTime
FROM    doctor AS dct
        LEFT JOIN ( SELECT  *
                    FROM    Nosource
                    WHERE   DATEDIFF(day, GETDATE(), workTime) > 0
                  ) AS nos ON dct.docNumber = nos.docNumber
GROUP BY dct.ID ,
        dct.NAME ,
        dct.docNumber ,
        nos.workTime

Vuelva a realizarlo y resultará correcto, que es el resultado de cumplir con los requisitos. La idea es: solo es necesario filtrar la tabla correcta, usar el conjunto de resultados filtrado (usando una subconsulta) como la tabla derecha de la consulta de combinación, y luego conectar y agrupar ...

De hecho, escribir declaraciones SQL concisas y de alto rendimiento requiere fuertes habilidades de pensamiento lógico (inseparables de las matemáticas) y experiencia. Existe una forma más sencilla de escribir:

SELECT  sum(case when nos.workTime>getdate then 1 else 0 end) AS PersonNumSounceCOUNT , --总数
dct.ID AS docID ,
dct.NAME ,
dct.docNumber 
FROM    doctor AS dct
LEFT JOIN Nosource AS nos ON dct.docNumber = nos.docNumber
GROUP BY dct.ID ,
dct.NAME ,
dct.docNumber 


Para explicarlo de esta manera, no sé si todos pueden entenderlo. De todos modos, la idea general es así. La capacidad expresiva y el nivel del autor son ciertamente limitados, y es inevitable que haya desviaciones, ¡espero que los lectores lo comprendan!



Este artículo es de http://blog.csdn.net/dinglang_2009 , indique la fuente para la reimpresión.





Supongo que te gusta

Origin blog.csdn.net/dinglang_2009/article/details/7888506
Recomendado
Clasificación