在具有复合 PK 的表上使用两次 where in 是否足够?

发布于 12-21 01:41 字数 1179 浏览 3 评论 0原文

我有一个查询

SELECT * 
FROM table1
WHERE
documentId in
(
   --select items from a second table where a third column happens to be null
   select documentId from table2 t2 inner join table1 t1
   on t1.documentId = t2.documentId and t1.itemId = t2.ItemId
   WHERE t1.someOtherColumn is null
)
and itemId in
(
   --similar query as above, just selecting itemId now
   select itemId from table2 t2 inner join table1 t1
   on t1.documentId = t2.documentId and t1.itemId = t2.ItemId
   WHERE t1.someOtherColumn is null
)
order by 1

鉴于 table1 具有复合 PK = documentId + itemId,这是否足以仅从 table1 中选择唯一的值?我担心的是,可能会出现 documentId 存在且 itemId 存在的情况,但由于它们没有一起查看,因此可能会做出错误的选择。

例如,

假设存在一个值

documentId = 1 且 itemId = 1。

假设没有组合键

documentId = 1 且 itemId = 1。

我不需要复合键

[documentId = 1 且 itemId = 3]

要包含的

。我也不想要复合键

[documentId = 2 且 itemId = 1]

要包含的

。如果后来添加了复合键(现在不存在)

[documentId = 1 且 itemId = 1]

那么它应该被包含在内。

I have a query

SELECT * 
FROM table1
WHERE
documentId in
(
   --select items from a second table where a third column happens to be null
   select documentId from table2 t2 inner join table1 t1
   on t1.documentId = t2.documentId and t1.itemId = t2.ItemId
   WHERE t1.someOtherColumn is null
)
and itemId in
(
   --similar query as above, just selecting itemId now
   select itemId from table2 t2 inner join table1 t1
   on t1.documentId = t2.documentId and t1.itemId = t2.ItemId
   WHERE t1.someOtherColumn is null
)
order by 1

Given that table1 has composite PK = documentId + itemId, is this sufficient to select only values from table1 that are unique? My fear is that a situation may occur where documentId exists and itemId exists, but since they are not looked at together then incorrect selections can be made.

For example,

Let's assume that there exists a value

documentId = 1 and itemId = 1.

Let's assume there is no composite key

documentId = 1 and itemId = 1.

I do not want composite key

[documentId = 1 and itemId = 3]

to be included.

I also do not want composite key

[documentId = 2 and itemId = 1]

to be included.

If there were a composite key added later (it's not there now)

[documentId = 1 and itemId = 1]

then it should be included.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

执着的年纪2024-12-28 01:41:46

这将执行相同的操作,而无需使用连接或两个 IN

SELECT *
FROM table1
WHERE exists
(
    SELECT 1
    FROM table2
    WHERE someOtherColumn is null
        AND table1.documentId = table2.documentId
        AND table1.itemId = table2.ItemId
)
ORDER BY 1

This would do the same without having to use a join nor two INs

SELECT *
FROM table1
WHERE exists
(
    SELECT 1
    FROM table2
    WHERE someOtherColumn is null
        AND table1.documentId = table2.documentId
        AND table1.itemId = table2.ItemId
)
ORDER BY 1
瞄了个咪的2024-12-28 01:41:46

您的假设是正确的,这可能会导致错误的结果。你可以使用这个:

SELECT table1.* 
FROM table1
WHERE someOtherColumn IS NULL
  AND (documentId, itemId ) IN
   (
   SELECT documentId, itemId 
   FROM table2 t2                  --- no need for table1 again here 
   )
ORDER BY 1

更新:我认为上面的内容在 SQL-Server 中不起作用,仅在 Postgres(和 Oracle?)中。无论如何,这应该适用于大多数系统:

SELECT table1.* 
FROM table1
WHERE someOtherColumn IS NULL
  AND EXISTS
   (
   SELECT documentId, itemId FROM table2 t2     
   WHERE table2.documentId = table1.documentId
     AND table2.itemId = table1.itemId
   )
ORDER BY 1

You are correct assuming that it may lead to erroneous results. You could use this:

SELECT table1.* 
FROM table1
WHERE someOtherColumn IS NULL
  AND (documentId, itemId ) IN
   (
   SELECT documentId, itemId 
   FROM table2 t2                  --- no need for table1 again here 
   )
ORDER BY 1

Update: I think the above does not wotk in SQL-Server, only in Postgres (and Oracle?). Anyway, this should work in most systems:

SELECT table1.* 
FROM table1
WHERE someOtherColumn IS NULL
  AND EXISTS
   (
   SELECT documentId, itemId FROM table2 t2     
   WHERE table2.documentId = table1.documentId
     AND table2.itemId = table1.itemId
   )
ORDER BY 1
世界等同你2024-12-28 01:41:46

这个怎么样:

SELECT * 
FROM table1,
(
   select documentId, itemid from table2 t2 inner join table1 t1
   on t1.documentId = t2.documentId and t1.itemId = t2.ItemId
   WHERE someOtherColumn is null
) t
WHERE
table1.documentId = t.documentid
and table1.itemId = t.itemid
order by 1

how about this:

SELECT * 
FROM table1,
(
   select documentId, itemid from table2 t2 inner join table1 t1
   on t1.documentId = t2.documentId and t1.itemId = t2.ItemId
   WHERE someOtherColumn is null
) t
WHERE
table1.documentId = t.documentid
and table1.itemId = t.itemid
order by 1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文