2012-04-04 26 views
1

如何返回不同的记录具有数据的Oracle表下面的示例称为MY_ATTRIBUTES:基于两个不同的值

Date  Emp_No Attribute 
----------------------------------------------------- 
01/04/2012 1234567 APPLE 
01/04/2012 1234567 ORANGE 
01/04/2012 1234567 PINEAPPLE 
01/04/2012 1234567 BANANA 
01/04/2012 8888888 APPLE 
01/04/2012 8888888 ORANGE 
01/04/2012 2222222 APPLE 
01/04/2012 2222222 ORANGE 
01/04/2012 2222222 PINEAPPLE 

基于以上的样本数据,我需要回到只有仅使用重复的记录日期和EMP_NO其中这些记录包含有“苹果”和“菠萝”

因此,基于这一标准的两种属性的数据,我只想到了以下两个结果记录,即:

01/04/2012 1234567 
01/04/2012 2222222 

希望有人可以协助Oracle SQL查询,该查询将根据所描述的条件返回此结果集。

对不起,应该也指出我需要这个SQL查询作为主查询的子查询使用。

谢谢。

+0

您的问题包含答案...当你重复的记录使用不同的功能。 ..例如选择与表格不同,其中..... – 2012-04-04 06:22:10

+0

了解你在说什么,但我不确定如何拉出属性为APPLE和PINEAP的记录PLE。 – tonyf 2012-04-04 06:32:21

+0

你可以使用IN函数..或UNION ..选择不同的日期,emp_no从(选择*从表where属性=苹果联盟选择*从表属性=苹果).... – 2012-04-04 06:57:59

回答

2

尝试

SELECT DISTINCT A.Date, A.Emp_no 
FROM (SELECT * FROM MY_ATTRIBUTES WHERE ATTRIBUTE = 'APPLE') A 
INNER JOIN (SELECT * FROM MY_ATTRIBUTES WHERE ATTRIBUTE = 'PINEAPPLE') B ON B.Date = A.Date AND B.Emp_No = A.Emp_No 
2

有可能是一个更有效的方式,但是这应该工作:(除权相同的日期和EMP 2个苹果)

SELECT DISTINCT DATE, EMP_NO 
FROM (
    SELECT DATE, EMP_NO 
    FROM MY_ATTRIBUTES 
    WHERE ATTRIBUTE = 'APPLE' 
    INTERSECT 
    SELECT DATE, EMP_NO 
    FROM MY_ATTRIBUTES 
    WHERE ATTRIBUTE = 'PINEAPPLE' 
); 
+0

这一切工作正常,但我现在找到这样做的性能问题 - 关于如何加快/调整查询的任何想法? – tonyf 2012-04-04 07:13:53

+1

INTERSECT应该提供一组独特的组合,因此不需要DISTINCT子句,这会产生额外的排序。 – APC 2012-04-04 09:14:00

+0

@APC很好的捕获(投票评论),但我认为新的Oracle优化器知道它,并且不会这样做两次。我没有时间测试它... – 2012-04-04 10:47:18

2

如果没有重复这个因为有可能是更有效的无连接:

SELECT DATE, EMP_NO 
FROM MY_ATTRIBUTES 
WHERE ATTRIBUTE = 'APPLE' OR ATTRIBUTE = 'PINEAPPLE' 
GROUP BY DATE, EMP_NO 
HAVING COUNT(*) = 2 
+0

感谢barsju,但我实际上使用此查询要求作为子查询的一部分,但不幸的是我无法在子查询中使用GROUP BY。如果有作为子查询使用的解决方法,将不胜感激?谢谢。 – tonyf 2012-04-04 12:15:10

+0

那它必须是一个子查询吗?也许你应该发布整个查询,以便我们可以对此进行破解。 – barsju 2012-04-04 13:43:20

-1
SELECT DISTINCT DATE, EMP_NO 
WHERE ATTRIBUTE IN('APPLE','PINEAPPLE') 
+0

这将在DATE,EMP_NO组合与任一属性匹配时提供结果。 OP只需要具有两种记录的组合。 – APC 2012-04-04 09:16:11

-1
SELECT DISTINCT Emp_No, Date 
FROM (
    SELECT * 
    FROM MY_ATTRIBUTES m 
    WHERE m.Attribute IN ('Apple','Pineapple') 
) 
LIMIT 2 
ORDER BY Emp_No 
+0

这将在DATE,EMP_NO组合与任一属性相匹配时提供结果。 OP只需要具有两种记录的组合。此外,LIMIT不是Oracle语法,但即使它不会产生正确的效果。 – APC 2012-04-04 09:17:45

2

一个主题的变体:

with cte as 
(select date, empno, attribute 
    from my_attributes 
    where attribute in ('PINEAPPLE', 'APPLE')) 
select * 
from ( select date, emp_no 
     from cte 
     where attribute = 'PINEAPPLE' 
     intersect 
     select date, emp_no 
     from cte 
     where attribute = 'APPLE') 

任何这些解决方案的性能将取决于属性的选择性。如果你的碗里只有半打水果,你就会看到一张全桌侍者,只有很少的选项可以调整这些。另一方面,如果这个专栏是一个蔬菜水果店充满果味的美食(比如说150多个不同的价值),那么你应该从一个指数中得到回报。但是,这仍然取决于分布和偏斜:如果ATTRIBUTE是90%苹果和菠萝,那么您可能从索引中看不到任何好处:在这种情况下,全表扫描仍然是更好的选择。

TL;博士

调整是很难

0

你可以尝试以下方法:

SELECT DATE, EMP_NO FROM YOUR_TABLE WHERE ATTRIBUTE = 'APPLE' OR ATTRIBUTE = 'PINEAPPLE' GROUP BY DATE, EMP_NO HAVING COUNT(*) = 2;

+0

这已经回答了。 – 2012-04-04 10:43:53

+0

@FlorinGhita答案是否可以与实际答案有所不同?是的,你可以说它的风格不同 – harry 2012-04-04 11:25:35

+0

我不明白你在说什么。你的答案和barsju是一样的。他已经说过你的回复(4小时前),格式除外。对同一事物有两个答案是没有用的。 – 2012-04-04 13:01:38