一个 sql (oracle) 查询,用于获取每列有两个不同(空和非空)值的唯一信息
为了清楚起见,表 foobar 的结构如下:
id, action_dt, status_id 1, '02-JUL-10', 'x' 1, '02-JUL-10', '2' 1, '02-JUL-10', NULL 2, '02-JUL-10', 'a' 2, '02-JUL-10', 'b' 3, '02-JUL-10', 'k' 3, '02-JUL-10', NULL 3, '03-JUL-10', 'k' 3, '03-JUL-10', NULL
我需要一个查询来获取 ID,以便每个 ID 每天都存在一个 NULL 值和一个 NOT NULL 值。因此,在上面的示例数据集中,查询需要返回:
'02-JUL-10', 1 '02-JUL-10', 3 '03-JUL-10', 3
是的,可以使用类似以下内容来完成:
SELECT nulls.action_dt , nulls.id FROM (SELECT action_dt , id FROM foobar WHERE status_id IS NULL GROUP BY action_dt) nulls INNER JOIN (SELECT action_dt , id FROM foobar WHERE status_id IS NOT NULL GROUP BY action_dt) non_nulls ON nulls.action_dt = non_nulls.action_dt AND nulls.id = non_nulls.id
但正如您所看到的,除其他外,还有两个子查询和另一个用于连接的迭代...
我的查询一直致力于并希望具有以下形式:
SELECT action_dt , id FROM foobar GROUP BY action_dt , id , CASE WHEN status_id IS NOT NULL THEN 1 ELSE 0 END HAVING COUNT(prim_card_nb) > 1
但它并没有完全返回我需要的内容(如您所知,HAVING 子句适用于正在查询的基础数据)。有什么想法吗?
毕竟,似乎解决方案是将上述查询放在子查询中并以这种方式过滤它,例如:
SELECT action_dt , id FROM (SELECT action_dt , id FROM foobar GROUP BY action_dt , id , CASE WHEN status_id IS NOT NULL THEN 1 ELSE 0 END ) repeat_ids_per_day GROUP BY action_dt , id HAVING COUNT(id) > 1
但我觉得它可以更好......
Table foobar is, for clarity, structured and has data as follows:
id, action_dt, status_id 1, '02-JUL-10', 'x' 1, '02-JUL-10', '2' 1, '02-JUL-10', NULL 2, '02-JUL-10', 'a' 2, '02-JUL-10', 'b' 3, '02-JUL-10', 'k' 3, '02-JUL-10', NULL 3, '03-JUL-10', 'k' 3, '03-JUL-10', NULL
I need a query that gets IDs such that for each ID a NULL value and a NOT NULL value exists per day. So, in the example dataset above, the query needs to return:
'02-JUL-10', 1 '02-JUL-10', 3 '03-JUL-10', 3
Yes, it can be done using something like:
SELECT nulls.action_dt , nulls.id FROM (SELECT action_dt , id FROM foobar WHERE status_id IS NULL GROUP BY action_dt) nulls INNER JOIN (SELECT action_dt , id FROM foobar WHERE status_id IS NOT NULL GROUP BY action_dt) non_nulls ON nulls.action_dt = non_nulls.action_dt AND nulls.id = non_nulls.id
but as you can see, among other things, two subqueries and another iteration for the join...
The query I've been working on and have hopes for is of the form:
SELECT action_dt , id FROM foobar GROUP BY action_dt , id , CASE WHEN status_id IS NOT NULL THEN 1 ELSE 0 END HAVING COUNT(prim_card_nb) > 1
but it doesn't quite return what I need (as you know, the HAVING clause applies to the underlying data that is being queried). Any ideas?
After all this, it seems a solution would be to have the above query in a subquery and filter it down that way, such as:
SELECT action_dt , id FROM (SELECT action_dt , id FROM foobar GROUP BY action_dt , id , CASE WHEN status_id IS NOT NULL THEN 1 ELSE 0 END ) repeat_ids_per_day GROUP BY action_dt , id HAVING COUNT(id) > 1
but I feel it can be better...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的想法是合理的:在这种情况下,您不需要子查询,聚合就足够了,并且应该更有效。这应该有效:
Your idea is sound: in such a case you don't need a subquery, an aggregate is sufficient and should be more efficient. This should work:
我认为你必须在你的第一个发布的查询中做一些小的改变,
如下 -
你发布的内容不正确,就像在oracle数据库中一样。
选择时不能包含未分组的列名称。
所以请检查一下..这可能是你的错误..也可能是问题的原因..
I think you have to do some minor changes in your first posted query
as below -
what you have posted there is not a correct, as in oracle database..
you can't include not grouped column name while selecting..
so please check that .. it could be your mistake .. and may be it was couse of problem..