SELECT 具有复合键的 DISTINCT
SELECT DISTINCT with composite key
这是对我遇到的问题的简化,但使用此示例我想获取给定客户的所有产品记录。
给客户可能有很多订单,有些订单可能是同一产品我不想拉回重复的产品。
产品 table 上还有一个复合键。
在理想情况下,这很简单,下面的查询就可以完成这项工作。然而,由于 table 包含一个 nText 列,SQL 服务器抱怨 "The ntext data type cannot be selected as DISTINCT because it is not comparable."
SELECT distinct p.idA, p.idB, p.descriptionNTEXT
FROM p product, o order, c customer
WHERE o.productID = p.idA AND o.subProductID = p.idB AND o.customerID = c.ID
我想将其重组为
SELECT p1.idA, p1.idB, p1.descriptionNTEXT
FROM p1 product
WHERE (p1.idA, p1.idB) IN
(
SELECT p.idA, p.idB
FROM p product, o order, c customer
WHERE o.productID = p.idA AND o.subProductID = p.idB AND o.customerID = c.ID
)
参见 How do I (or can I) SELECT DISTINCT on multiple columns?
但是这种方法不适用于 SQL 服务器
有什么想法吗?
理想情况下,我需要一个 portable 解决方案,它至少可以在 SQLServer、MySQL 和 Oracle 上运行。但是针对数据库的解决方案总比没有好!
下面的数据大概就是我想要的了
Customer
ID name
1 Fred
Order
ID CustomerID productID subProductID
10 1 100 200
11 1 100 200
12 1 100 200
13 1 101 201
Product
IDA IDB descriptionNTEXT
100 200 'product 1'
101 201 'product 2'
102 203 'product 3'
Expected Result
IDA IDB descriptionNTEXT
100 200 'product 1'
101 201 'product 2'
将 NTEXT 转换为 NVARCHAR(MAX)
SELECT distinct p.idA, p.idB, cast (p.descriptionNTEXT as nvarchar(max))
FROM p product, o order, c customer
WHERE o.productID = p.idA AND o.subProductID = p.idB AND o.customerID = c.ID
IMPORTANT! ntext, text, and image data types will be removed in a
future version of SQL Server. Avoid using these data types in new
development work, and plan to modify applications that currently use
them. Use nvarchar(max), varchar(max), and varbinary(max) instead.
https://msdn.microsoft.com/en-us/library/ms187993.aspx
nvarchar [ ( n | max ) ] Variable-length Unicode string data. n
defines the string length and can be a value from 1 through 4,000. max
indicates that the maximum storage size is 2^31-1 bytes (2 GB). The
storage size, in bytes, is two times the actual length of data entered
+ 2 bytes. The ISO synonyms for nvarchar are national char varying and national character varying.
先做distinct,再join products。
select p.*
from (
select distinct CustomerID, productID, subProductID
from [Order]
) do
join Product p on p.productID = do.IDA and p.subProductID = do.IDB
查看您的代码,您似乎想在多个字段上使用 IN - 这可以通过 EXISTS 实现 - 它询问指定的查询是否 returns 任何行 - 所以根据你的查询可能是像
SELECT p1.idA, p1.idB, p1.descriptionNTEXT
FROM p1 product
WHERE EXISTS
(
SELECT 1
FROM p product, o order, c customer
WHERE o.productID = p.idA AND o.subProductID = p.idB AND o.customerID = c.ID
AND p1.idA = p.ida
AND p1.idB = p.idb
)
您可以在不将其转换为另一种类型的情况下进行尝试
SELECT p1.idA, p1.idB, p1.descriptionNTEXT
from product p1 where p1.IDA in( SELECT Distinct p.idA FROM product p,order o,customer c WHERE o.productID = p.idA AND o.subProductID = p.idB AND o.customerID = c.ID)
这是对我遇到的问题的简化,但使用此示例我想获取给定客户的所有产品记录。 给客户可能有很多订单,有些订单可能是同一产品我不想拉回重复的产品。 产品 table 上还有一个复合键。
在理想情况下,这很简单,下面的查询就可以完成这项工作。然而,由于 table 包含一个 nText 列,SQL 服务器抱怨 "The ntext data type cannot be selected as DISTINCT because it is not comparable."
SELECT distinct p.idA, p.idB, p.descriptionNTEXT
FROM p product, o order, c customer
WHERE o.productID = p.idA AND o.subProductID = p.idB AND o.customerID = c.ID
我想将其重组为
SELECT p1.idA, p1.idB, p1.descriptionNTEXT
FROM p1 product
WHERE (p1.idA, p1.idB) IN
(
SELECT p.idA, p.idB
FROM p product, o order, c customer
WHERE o.productID = p.idA AND o.subProductID = p.idB AND o.customerID = c.ID
)
参见 How do I (or can I) SELECT DISTINCT on multiple columns?
但是这种方法不适用于 SQL 服务器
有什么想法吗?
理想情况下,我需要一个 portable 解决方案,它至少可以在 SQLServer、MySQL 和 Oracle 上运行。但是针对数据库的解决方案总比没有好!
下面的数据大概就是我想要的了
Customer
ID name
1 Fred
Order
ID CustomerID productID subProductID
10 1 100 200
11 1 100 200
12 1 100 200
13 1 101 201
Product
IDA IDB descriptionNTEXT
100 200 'product 1'
101 201 'product 2'
102 203 'product 3'
Expected Result
IDA IDB descriptionNTEXT
100 200 'product 1'
101 201 'product 2'
将 NTEXT 转换为 NVARCHAR(MAX)
SELECT distinct p.idA, p.idB, cast (p.descriptionNTEXT as nvarchar(max))
FROM p product, o order, c customer
WHERE o.productID = p.idA AND o.subProductID = p.idB AND o.customerID = c.ID
IMPORTANT! ntext, text, and image data types will be removed in a future version of SQL Server. Avoid using these data types in new development work, and plan to modify applications that currently use them. Use nvarchar(max), varchar(max), and varbinary(max) instead.
https://msdn.microsoft.com/en-us/library/ms187993.aspx
nvarchar [ ( n | max ) ] Variable-length Unicode string data. n defines the string length and can be a value from 1 through 4,000. max indicates that the maximum storage size is 2^31-1 bytes (2 GB). The storage size, in bytes, is two times the actual length of data entered + 2 bytes. The ISO synonyms for nvarchar are national char varying and national character varying.
先做distinct,再join products。
select p.*
from (
select distinct CustomerID, productID, subProductID
from [Order]
) do
join Product p on p.productID = do.IDA and p.subProductID = do.IDB
查看您的代码,您似乎想在多个字段上使用 IN - 这可以通过 EXISTS 实现 - 它询问指定的查询是否 returns 任何行 - 所以根据你的查询可能是像
SELECT p1.idA, p1.idB, p1.descriptionNTEXT
FROM p1 product
WHERE EXISTS
(
SELECT 1
FROM p product, o order, c customer
WHERE o.productID = p.idA AND o.subProductID = p.idB AND o.customerID = c.ID
AND p1.idA = p.ida
AND p1.idB = p.idb
)
您可以在不将其转换为另一种类型的情况下进行尝试
SELECT p1.idA, p1.idB, p1.descriptionNTEXT
from product p1 where p1.IDA in( SELECT Distinct p.idA FROM product p,order o,customer c WHERE o.productID = p.idA AND o.subProductID = p.idB AND o.customerID = c.ID)