WHERE / GROUP按条件 - 一个名称但多个值

时间:2018-05-04 17:20:12

标签: mysql sql hql

我有下表:

Name          Product         
Bob           Car              
Bob           Apples
Bob           Pears
Bob           Car
John          Apples
John          Pears

无论谁购买了产品车,我都希望与其他人分开。所以,我创建了一个标志:

Name          Product       Flag        
Bob           Car             1  
Bob           Apples          0
Bob           Pears           0  
Bob           Car             1
John          Apples          0
John          Pears           0 

但是我的旗帜的问题是,即使我做了一个where条件并说,告诉我消费者WHERE标志!= 1,它会选择Bob。鲍勃拥有一辆汽车是不正确的。

我仍然希望GROUP by Product。

如何将上表分为两组?

谢谢!

5 个答案:

答案 0 :(得分:0)

使用以下查询: -

select name from table where flag!=1
and name not in (select name from table where flag = 1)
group by name

答案 1 :(得分:0)

您可以使用这两个查询。

Flag

<强>插图:

-- do not have Car
SELECT * 
FROM products
WHERE Name not in (SELECT DISTINCT Name 
                   FROM products 
                   WHERE Product='Car');

-- have Car
SELECT * 
FROM products
WHERE Name in (SELECT DISTINCT Name 
               FROM products 
               WHERE Product='Car');

答案 2 :(得分:0)

&#34;告诉我消费者WHERE标志!= 1,它会选择Bob&#34;那是因为你要求 where flag!= 1.相反,你需要一些更复杂的东西,比如:

> ## load libraries
> library(tidyverse)
> library(lubridate)
> 
> ## define times
> times <- c(1055289600, 1092182400, 1086220800, 1074556800, 1109289600, 
+            1041897600, 1069200000, 1047427200, 1072656000, 1048636800, 1092873600, 
+            1090195200, 1051574400, 1052179200, 1130371200, 1242777600, 1140652800, 
+            1137974400, 1045526400, 1111104000, 1073952000, 1052870400, 1087948800, 
+            1053993600, 1039564800, 1141603200, 1074038400, 1105315200, 1060560000, 
+            1072051200, 1046217600, 1107129600, 1088553600, 1071619200, 1115596800, 
+            1050364800, 1147046400, 1083628800, 1056412800, 1159747200, 1087257600, 
+            1201478400, 1120521600, 1066176000, 1034553600, 1057622400, 1078876800, 
+            1010880000, 1133913600, 1098230400, 1170806400, 1037318400, 1070409600, 
+            1091577600, 1057708800, 1182556800, 1091059200, 1058227200, 1061337600, 
+            1034121600, 1067644800, 1039478400, 1022198400, 1063065600, 1096329600, 
+            1049760000, 1081728000, 1016150400, 1029801600, 1059350400, 1087257600, 
+            1181692800, 1310947200, 1125446400, 1057104000, NA, 1085529600, 
+            1037664000, 1091577600, 1080518400, 1110758400, 1092787200, 1094601600, 
+            1169424000, 1232582400, 1058918400, 1021420800, 1133136000, 1030320000, 
+            1060732800, 1035244800, 1090800000, 1129161600, 1055808000, 1060646400, 
+            1028678400, 1075852800, 1144627200, 1111363200, 1070236800)
> times <- tibble(time = as.POSIXct(times, origin = "1970-01-01", tz = "UTC")) %>% 
+   mutate(time = as_date(time),
+          duplicated = duplicated(time)) ## there are duplicated times!
> 
> 
> ## define years
> year <- c("YEAR_1", "YEAR_2", "YEAR_3")
> interval <- c(interval(ymd("2002-09-01", tz = "UTC"), ymd("2003-08-31", tz = "UTC")),
+               interval(ymd("2003-09-01", tz = "UTC"), ymd("2004-08-31", tz = "UTC")),
+               interval(ymd("2004-09-01", tz = "UTC"), ymd("2005-08-31", tz = "UTC")))
> years <- tibble(year, interval)
> 
> ## check data
> times
# A tibble: 100 x 2
   time       duplicated
   <date>     <lgl>     
 1 2003-06-11 FALSE     
 2 2004-08-11 FALSE     
 3 2004-06-03 FALSE     
 4 2004-01-20 FALSE     
 5 2005-02-25 FALSE     
 6 2003-01-07 FALSE     
 7 2003-11-19 FALSE     
 8 2003-03-12 FALSE     
 9 2003-12-29 FALSE     
10 2003-03-26 FALSE     
# ... with 90 more rows
> years
# A tibble: 3 x 2
  year   interval                      
  <chr>  <S4: Interval>                
1 YEAR_1 2002-09-01 UTC--2003-08-31 UTC
2 YEAR_2 2003-09-01 UTC--2004-08-31 UTC
3 YEAR_3 2004-09-01 UTC--2005-08-31 UTC
> 
> ## create new indicator variavble
> ##
> ## join datasets (length = 3 x 100)
> ## indicator for year
> ## drop NAs
> ## keep "time" and "active"
> ## join with times to get back at full dataset
> ## as duplications, keep only one of them
> crossing(times, years) %>% 
+   mutate(active = if_else(time %within% interval, year, NA_character_)) %>% 
+   drop_na(active) %>% 
+   select(time, active) %>% 
+   right_join(times, by = "time") %>% 
+   distinct() %>% 
+   select(-duplicated)
# A tibble: 100 x 2
   time       active
   <date>     <chr> 
 1 2003-06-11 YEAR_1
 2 2004-08-11 YEAR_2
 3 2004-06-03 YEAR_2
 4 2004-01-20 YEAR_2
 5 2005-02-25 YEAR_3
 6 2003-01-07 YEAR_1
 7 2003-11-19 YEAR_2
 8 2003-03-12 YEAR_1
 9 2003-12-29 YEAR_2
10 2003-03-26 YEAR_1
# ... with 90 more rows

或者,您可以执行LEFT JOIN,这可能会也可能不会更快,具体取决于您拥有的数据量及其值的分布方式。

SELECT DISTINCT Name
FROM tableTable
WHERE Name NOT IN (SELECT Name FROM theTable WHERE Product = 'Car')

这将获得除汽车以外的产品的所有行,然后将LEFT JOIN与IS NULL条件结合使用,以找到哪些行也没有“汽车”。行。

答案 3 :(得分:0)

我认为您希望显示您的表格数据,只需使用&#34;购买汽车的人员&#34; 分区(未分组)以某种方式分开 - 例如,这可以使用$子句来完成。

步骤1:确定购买汽车的人:

ORDER BY OwnsACar

第2步:加入此数据以生成计算的&#34; SELECT DISTINCT Name FROM yourTable WHERE Product = 'Car' &#34;柱:

OwnsACar

答案 4 :(得分:0)

尝试:

>>> [[b+a for a,b in zip(i,j)] for i,j in zip(list1, list2)]
[['a= 0\n', 'b= 1\n', 'c= 2\n', 'd= 3\n', 'e= 4\n'], ['a= 0\n', 'b= 1\n', 'c= 2\n']]

虽然您可以通过以下方式离开标志栏:

SELECT `t`.`Name`, `t`.`Product`, SUM(`t`.`Flag`) as hasCar
FROM your_table t
GROUP BY `t`.`Name`
HAVING `t`.`hasCar` = 0;