简体   繁体   English

如果条件不适用于IN子句

[英]Where condition not working with IN Clause

I have a query. 我有一个查询。 In this query I am using a sub query to get the data from the same table with different condition and in the main query I am mentioning the ids that are used to get data in the sub query and putting a condition that the values that are being considered in the main query with the ids should not be empty. 在此查询中,我使用子查询从具有不同条件的同一张表中获取数据,在主查询中,我提到了用于在子查询中获取数据的ID,并提出了一个条件,即在具有ID的主查询中考虑的内容不应为空。 If I use a single ID with IN clause in the main query, my query works fine but if I use multiple ids in the main query and add the clause that the values should not be empty, the query does not give me the desired result.Here is my query 如果在主查询中使用带有ID子句的单个ID,则查询工作正常,但如果在主查询中使用多个ID并添加该值不应为空的子句,则查询不会给我期望的结果。这是我的查询

SELECT e.id AS `Personal Number`,
e.date AS `Date`,
CONCAT(ep.firstname,' ',ep.lastname) AS `Employee Name`,
IF(ep.sex='M','Male','Female') AS sex,
DATE_FORMAT(p.birthdate,'%m/%d/%Y')AS birthdate,
(SELECT `value` FROM employee_data WHERE history=87 AND DATE=e.date) AS `A`,
(SELECT `value` FROM employee_data WHERE history=603 AND DATE=e.date) AS `B`,
(SELECT `value` FROM employee_data WHERE history=82 AND DATE=e.date) AS `C`,
(SELECT `value` FROM employee_data WHERE history=86 AND DATE=e.date) AS `D`
FROM tbl e  
INNER JOIN employee ep ON e.id = ep.id
INNER JOIN tbl2 ap ON ap.date=e.date
INNER JOIN employee_data AS phd ON e.date = phd.date   
WHERE (phd.history IN(82,87,603,86) AND phd.value!='')  AND ap.date BETWEEN '2013-01-01' AND '2013-09-01'AND e.status!='cancelled'. 

I am out of ideas that what to do with this query. 我不知道如何处理此查询。 Can anyone help. 谁能帮忙。 Thanks in advance 提前致谢

Since you fetch values with filter in select clause, do a group by and get max() value in select clause. 由于您在select子句中使用filter来获取值,因此请执行group by并在select子句中获取max()值。

max (SELECT `value` FROM employee_data WHERE history=87 AND DATE=e.date) AS `A`,
max (SELECT `value` FROM employee_data WHERE history=603 AND encounter_nr=e.encounter_nr)     AS `B`,
max (SELECT `value` FROM employee_data WHERE history=82 AND encounter_nr=e.encounter_nr) AS `C`,
max  (SELECT `value` FROM employee_data WHERE history=86 AND encounter_nr=e.encounter_nr) AS `D`
FROM

Here is your problem. 这是你的问题。 Your query is producing four rows when you have the where clause. 当您拥有where子句时,查询将产生四行。 But, I suspect that you are just expecting one row, or at least, just one row per id. 但是,我怀疑您只希望每个ID排一行,或者至少只有一行。

I think this is the query that you want: 我认为这是您想要的查询:

SELECT e.id AS `Personal Number`, e.date AS `Date`,
       CONCAT(ep.firstname,' ',ep.lastname) AS `Employee Name`,
       IF(ep.sex='M','Male','Female') AS sex,
       DATE_FORMAT(p.birthdate,'%m/%d/%Y') AS birthdate,
       max(case when history = 87 then value end) as A,
       max(case when history = 603 then value end) as B,
       max(case when history = 82 then value end) as C,
       max(case when history = 86 then value end) as D
FROM tbl e INNER JOIN
     employee ep
     ON e.id = ep.id INNER JOIN
     tbl2 ap ON ap.date = e.date INNER JOIN
     employee_data phd
     ON e.date = phd.date   
WHERE phd.history IN (82, 87, 603, 86) AND phd.value <> '' AND
      ap.date BETWEEN '2013-01-01' AND '2013-09-01' AND
      e.status <> 'cancelled'
group by e.id;

This should return one row for each employee. 这将为每位员工返回一行。

EDIT: 编辑:

It occurs to me that you might not want an aggregation. 在我看来,您可能不希望进行汇总。 You can follow your original approach by removing the join to employee_data in the outer query: 您可以通过删除外部查询中对employee_data的联接来遵循原始方法:

SELECT e.id AS `Personal Number`, e.date AS `Date`,
       CONCAT(ep.firstname,' ',ep.lastname) AS `Employee Name`,
       IF(ep.sex='M','Male','Female') AS sex,
       DATE_FORMAT(p.birthdate,'%m/%d/%Y') AS birthdate,
       (SELECT `value` FROM employee_data WHERE history=87 AND DATE=e.date) AS `A`,
       (SELECT `value` FROM employee_data WHERE history=603 AND DATE=e.date) AS `B`,
       (SELECT `value` FROM employee_data WHERE history=82 AND DATE=e.date) AS `C`,
       (SELECT `value` FROM employee_data WHERE history=86 AND DATE=e.date) AS `D`
FROM tbl e INNER JOIN
     employee ep
     ON e.id = ep.id INNER JOIN
     tbl2 ap ON ap.date = e.date
WHERE ap.date BETWEEN '2013-01-01' AND '2013-09-01'AND e.status <> 'cancelled'
HAVING A <> '' and B <> '' and C <> '' and D <> '';

The having clause is a MySQL trick that lets you refer to column aliases in the from clause. having子句是一个MySQL技巧,可让您在from子句中引用列别名。 It does not imply aggregation in this case. 在这种情况下,它并不意味着聚合。

You would do this if you had an index employee_data(history, date) . 如果您有索引employee_data(history, date)则可以执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM