我有两张桌子: -
ITEM(ITEM_ID, ITEM_NAME)
STATS(ITEM_ID, STAT_ID, STAT_VALUE)
我想将ITEM_IDs
与STATS
完全相同,但它位于SQL Server Compact上(无EXCEPT
或INTERSECT
)
例如:
STATS:-
1 12 100
1 13 500
2 12 200
2 14 300
3 12 100
3 13 500
4 12 100
应该返回1和3的行(相同的统计数据/值12/100和13/500)
没有INTERSECT
可以吗?
答案 0 :(得分:4)
在ITEM表中使用内部联接,并在条件上使用您希望在该表上看到的任何内容
答案 1 :(得分:3)
第一次我完全错了: - )
找到相同集合的标准方法"很难理解,大表通常表现不好,因为它们涉及将所有内容与其他所有内容进行比较(类似于CROSS JOIN)。
AFAIK SQL Server CE也支持XML函数,因此最好的方法是Vladimir Baranov在现有答案中描述的那个:
with cte as
( -- group concat all rows for one ITEM_ID into one big string
SELECT distinct ITEM_ID,
(select '#' + rtrim(STAT_ID) + ',' + rtrim(STAT_VALUE)
from STATS as t2
where t1.ITEM_ID = t2.ITEM_ID ORDER BY STAT_ID FOR XML PATH('') ) as rowsConcat
FROM STATS as t1
),
cnts as
( -- how many rows exist for that concatenated string?
select *
,count(*)
over (partition by rowsConcat) as cnt
from cte
)
select ITEM_ID
,dense_rank() -- assign the same group number to the duplicates
over(order by rowsConcat) as duplicateGroup
from cnts
where cnt > 1 -- more than one
答案 2 :(得分:3)
以下是我将如何处理此类任务。
第1步。拥有一个函数/方法,可将多列中的值合并为一列。在您的情况下,我们希望将两个值STAT_ID
和STAT_VALUE
放在一起。在这种情况下,简单转换为字符串和连接就足够了。所以,有两列的行:
STAT_ID STAT_VALUE
12 100
成为一列有一列:
single_value
12_100
此转换的结果应该是这样的表:
ITEM_ID single_value
1 12_100
1 13_500
2 12_200
2 14_300
3 12_100
3 13_500
4 12_100
第2步。有一些Aggregate函数接受多行中的值,并返回一个值作为长连接字符串。它可以是CLR函数,T-SQL函数或FOR XML
构造。您可以根据SQL Server CE支持的内容选择一个。
此转换的结果应该是这样的表:
ITEM_ID aggregated_single_value
1 12_100__13_500
2 12_200__14_300
3 12_100__13_500
4 12_100
第3步。获得此结果后,您只需GROUP BY aggregated_single_value
和COUNT
有多少ITEM_IDs
具有完全相同的值集。然后,只返回ITEM_IDs
计数超过1的HAVING
。
aggregated_single_value Count
12_100__13_500 2
12_200__14_300 1
12_100 1
修改强>
整体方法仍然适用于SQL Server CE的限制。
FOR XML
,用户定义的函数,CLR - 手动进行聚合"。它看起来像supports cursors。打开光标 - 使用正确的顺序扫描表格,聚合值并将它们保存到临时表格。varbinary(max)
或varchar(max)
等大型类型?如果是 - 很好,如果不是 - 您将被限制为varchar(8000)
或varbinary(8000)
。如果ITEM_ID
表中的同一STATS
最多有两行(或大约),则8000字节就足够了。此外,至少有一种简单粗略的方法来限制游标处理的行数。首先对ITEM_ID
表中的每个STATS
执行简单的行计数,并仅保留具有匹配计数的IDs
行。换句话说,过滤掉明显的不匹配。此步骤将从您的示例中删除ID=4
。
答案 3 :(得分:2)
我不确定SQL Server Compact
是否支持内部查询,但这个概念应该有效:
select distinct a.item_id
from stats a
where exists(select 1
from stats b
where a.stat_d=b.stat_id
and a.stat_value=b.stat_value)
答案 4 :(得分:2)
<强>
procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin // here some code end; procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin // more code here end; procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin // here other code end;
强>
返回INTERSECT
操作数左侧和右侧的查询返回的任何不同值。
使用INTERSECT
的替代方法是使用INTERSECT
,如下所示:
JOIN
等于
SELECT A.*
FROM A -- [A: ID, Name]
INTERSECT
SELECT B.*
FROM B -- [B: ID, Name]
或使用SELECT DISTINCT A.*
FROM A
JOIN (
SELECT B.*
FROM B) B1 ON A.ID = B1.ID AND A.Name = B1.Name
:
EXISTS
尝试此查询:
SELECT DISTINCT A.*
FROM A
WHERE EXISTS (
SELECT 1
FROM B WHERE A.ID = B.ID AND A.Name = B.Name)