【问题标题】:colors exist or not in sql serversql server中是否存在颜色
【发布时间】:2021-01-06 07:49:26
【问题描述】:

您好,我对 sql server 有一个疑问。 如果不存在,如何查找存在或不存在的颜色 然后获取productid信息

表:产品信息

CREATE TABLE [dbo].[productInfo](
    [Productid] [int] NULL,
    [Productcolor] [varchar](50) NULL
) 

INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (1, N'red')
INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (1, N'blue')
INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (1, N'white')
INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (2, N'red')
INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (2, N'blue')
INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (3, N'red')
INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (4, N'red')
INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (4, N'blue')
INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (4, N'white')

基于上述数据,我想要如下所示的输出

Productid | Productcolor
2         | white missed
3         | blue missed
3         | white missed

每个 productid 应该有红色、蓝色、白色。如果不存在任何颜色,则 需要显示productid和color。如果所有颜色都存在则不需要显示productid

我尝试如下

select * 
from productinfo 
where Productcolor not in ( 'red','blue','white')

能否请您告诉我如何编写查询以在 sql server 中完成此任务。

【问题讨论】:

    标签: sql-server sql-server-2012


    【解决方案1】:

    请您尝试以下方法:

    SELECT P.PRODUCT_ID,C.Productcolor
    FROM
     (
        SELECT DISTINCT PRODUCTID AS PRODUCT_ID FROM DBO.productInfo
     )P
    CROSS JOIN
    (
      SELECT DISTINCT PRODUCTCOLOR 
        FROM DBO.productInfo
    )C
     EXCEPT
     SELECT X.PRODUCTID,X.PRODUCTCOLOR
      FROM DBO.productInfo AS X 
    

    【讨论】:

    • 如果输入表只有一行(INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (1, N'red')),这种方法不会返回预期的结果。
    【解决方案2】:

    一种可能的方法是使用EXCEPT 集合运算符和具有所有可能颜色的VALUES 表值构造函数:

    SELECT DISTINCT p.Productid, v.Productcolor
    FROM productInfo p
    CROSS APPLY (VALUES ('red'), ('blue'), ('white')) v (Productcolor)
    EXCEPT
    SELECT p.Productid, p.Productcolor
    FROM productInfo p
    

    结果:

    Productid   Productcolor
    2           white
    3           blue
    3           white
    

    【讨论】:

    • @user3224208 如果您认为这个或任何其他答案是您问题的最佳解决方案,您可以accept 它。只能接受一个答案。
    【解决方案3】:

    另一种方法是使用半反连接:

    SELECT T.Productcolor, T.Productid
    FROM   productInfo  AS CLP
           RIGHT OUTER JOIN (SELECT DISTINCT C.Productcolor, P.Productid
                             FROM   productInfo  AS C
                                    CROSS JOIN productInfo  AS P) AS T
              ON CLP.Productid = T.Productid AND CLP.Productcolor = T.Productcolor
    WHERE  CLP.Productid IS NULL;
    

    可以编写其他一些查询...使用 NOT EXISTS :

    SELECT CP.*
    FROM   (SELECT DISTINCT C.Productcolor, P.Productid
            FROM   productInfo   AS C
                   CROSS JOIN productInfo   AS P) AS CP
    WHERE  NOT EXISTS(SELECT *
                      FROM   productInfo   AS C
                      WHERE  CP.Productid = C.Productid AND CP.Productcolor = C.Productcolor);
    

    或者有一个相关的 NOT IN :

    SELECT CP.*
    FROM   (SELECT DISTINCT C.Productcolor, P.Productid
            FROM   productInfo   AS C
                   CROSS JOIN productInfo   AS P) AS CP
    WHERE  CP.Productcolor NOT IN(SELECT Productcolor
                                 FROM   productInfo AS C
                                 WHERE  CP.Productid = C.Productid);
    

    【讨论】:

    • 请检查这条语句的执行结果,如果输入表只有一行(INSERT [dbo].[productInfo] ([Productid], [Productcolor]) VALUES (1, N'red'))
    • 之所以有效,是因为颜色是从唯一的表中提取的...
    【解决方案4】:
    SELECT *
    FROM productInfo p
    WHERE NOT EXISTS (SELECT 1 FROm productInfo pBlue WHERE pBlue.Productcolor='blue' and pBlue.Productid=p.Productid)
      OR NOT EXISTS (SELECT 1 FROm productInfo pRed WHERE pRed.Productcolor='red' and pRed.Productid=p.Productid)
      OR NOT EXISTS (SELECT 1 FROm productInfo pWhite WHERE pWhite.Productcolor='white' and pWhite.Productid=p.Productid);
    

    在将执行计划与此处给出的其他答案进行比较时,可能需要更多的打字工作,但应该更快。

    【讨论】:

      猜你喜欢
      • 2010-11-15
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 2010-09-30
      • 2012-07-29
      相关资源
      最近更新 更多