I'm trying to inner join table1 <- to -> table2, table3, table4 OR table5 depending on a field present in table1. So, if the field information in table1 has the value example_get_from_two I should inner join table1 with table2 as to obtain a given row, if in another row table1 has the value example_get_from_three I should inner join table1 with table3 and so on. This is the query I tried, but it returned zero rows:
SELECT n.notification_type,
(CASE WHEN n.notification_type = 'two' AND n.information = t2.somefield
THEN t2.anotherfield
WHEN n.notification_type = 'three'
THEN (CASE WHEN t3.field = '1' THEN t3.otherfield ELSE t3.yetanotherfield END)
WHEN n.notification_type = 'four' AND t4.field = n.information
THEN t4.anotherfield
WHEN n.notification_type = 'five'
THEN t5.field
END) AS information FROM table0 zero, notifications n
INNER JOIN table1 t1 ON(n.information=t1.somefield AND n.notification_type = 'something')
INNER JOIN table2 t2 ON(n.information=t2.somefield AND n.notification_type = 'something')
INNER JOIN table3 t3 ON((n.information=t3.somefield OR n.information=t3.someotherfield) AND n.notification_type = 'something')
WHERE zero.field ='something' AND n.id = zero.id
Unfortunately this retrieves zero rows and shouldn't , probably because all joins are made despite the actual value of information, and n.notification_type = "something". Is this possible with cases or similar? What I'd like to obtain is
fromfield1 | fromfield2 | fromfield3 (this one is "dynamic" and
depends on the joined table)
Related
Thanks for assisting with the previous query (SQL Query that selects a column in table 1 and uses that to select sum in table 2) of SUM from 2 tables, I now have a additional Condition for 1 of the tables. I would like to add WHERE Group1 = 1 AND IN/OUT = 'OUT'
I have 3 tables,
Names ,Groups
Names ,Payments
Names ,Payments and IN/OUT
I want to only SUM the OUT Payments in Table 3, I am getting total payments only So FAR is have:
SELECT t1.name1, SUM(t2.sale2),SUM(t3.sale3)
FROM table1 t1 JOIN table2 t2 ON t1.name1 = t2.name2
JOIN table3 t3 ON t1.name1 = t3.name3
WHERE group1 = 1
GROUP BY t1.name1
i would also like to add a zero if there is no data to sum instead of removing the whole record, Currently if a name has no payments in Table 3 but has payments in table 2 it deletes the record.
Please check the query below =>
To Get OutPayment group by Name
SELECT t1.Names,SUM(t3.Payments) As OutPayment
FROM TABLE3 as t3
INNER JOIN TABLE1 as t1 ON t1.Names = t3.Names
INNER JOIN TABLE2 as t2 ON t1.Names = t2.Names
WHERE t1.GroupID = 1 AND t3.INOROUT=2 --INOROUT =2 is OUT and 1 is IN
GROUP BY t1.Names;
To Get TotalOutPayment
SELECT SUM(t3.Payments) As TotalOutPayment
FROM TABLE3 as t3
INNER JOIN TABLE1 as t1 ON t1.Names = t3.Names
INNER JOIN TABLE2 as t2 ON t1.Names = t2.Names
WHERE t1.GroupID = 1 AND t3.INOROUT=2; --INOROUT =2 is OUT and 1 is IN
Note: Code is in DBFiddle too Check the Demo Query Link
So I have two tables with:
t1 = (submission_id,field_id,value),
t2 = (submission_id, other_fields....).
Now t1 contains a bunch of things in value, i.e. field_id = 8 gives value = firstname, field_id = 9 gives value = lastname etc. What I want is a table with (submission_id,firstname,lastname,...).
What I have some up with so far is something like this:
SELECT (SELECT value FROM t1 INNER JOIN t2 ON (t2.submission_id = t1.submission_id)
where field_id = 8),
(SELECT value FROM t1 INNER JOIN t2 ON (t2.submission_id = t1.submission_id) where field_id = 9)
But this just gives me an error about the fact that there is more than one result to each sub-query. I could use union, but this obviously just gives me horribly stacked results.
Anyone have any better idea?
If you don't need the join to t2 then do a self join:
SELECT t1a.submission_id, t1a.value firstname, t1b.value lastname
FROM t1 t1a INNER JOIN t1 t1b
ON t1b.submission_id = t1a.submission_id AND t1a.field_id = 8 AND t1b.field_id = 9
I kept the join on submission_id if this is the link between the 2 values.
One solution that is quite scalable is to use conditional aggregation:
select
submission_id,
max(case when field_id = 8 then value end) firstname,
max(case when field_id = 9 then value end) lasstname
from t1
group by submission_id
The advantage of this technique is that you can easily add more columns by extending the query with more max(case ...) expressions, so it scales better than the self-join solution.
If for some reason you also need to bring t2, then you can join and add columns from t2 in the from and group by clauses:
select
t1.submission_id,
t2.other_field1,
t2.other_field2,
max(case when t1.field_id = 8 then t1.value end) firstname,
max(case when t1.field_id = 9 then t1.value end) lasstname
from t1
inner join t2 on t2.submission_id = t1.submission_id
group by t1.submission_id, t2.other_field1, t2.other_field2
I have been using the following SQL:
SELECT DISTINCT NAME
FROM Events t1
LEFT JOIN UserHistory t2 ON t1.Name = t2.Event
WHERE t2.Event IS NULL
To select all rows from table 1 where table 2 is Null. This effectively filters out all my Table 1 data where Table 2 has data. However, I want to apply this only when a column in table 2 equals a certain value. Therefore I am looking to do a SELECT * FROM t2 WHERE t2.ID = 1 but am unsure how this fits into this query.
SELECT DISTINCT NAME
FROM Events t1
LEFT JOIN UserHistory t2 ON t1.Name = t2.Event and t2.certain_column = 1234
WHERE t2.Event IS NULL
Also you can try query with NOT EXISTS:
SELECT DISTINCT NAME
FROM Events t1
WHERE NOT EXISTS(SELECT * FROM UserHistory t2
WHERE t1.Name = t2.Event AND t2.ID = 1)
You need to add the predicate to the JOIN condition:
SELECT DISTINCT NAME
FROM Events t1
LEFT JOIN UserHistory t2 ON t1.Name = t2.Event AND t2.ID = 1
WHERE t2.Event IS NULL;
If you add it to the WHERE you effectively turn your outer join into an inner join, meaning no rows will be returned (since NULL = 1 evaluates to false)
I have 3 tables: table1, table2 & table3
I make a select query from table1 which LEFT JOINS the other two tables. In the select I have a group_concat which takes a value from table3. Everything works well until a row with a specific row doesn't exist. The group_concat list becomes empty. Instead, I would like it to set values in the group_concat to NULL for the ones where the rows doesn't exist.
Like I said if the value in table3 exist for all the rows in table2 then it works. If not, the whole group_concat is empty.
Some "simplified" code of what I got so far:
SELECT
table1.table2Id,
table1.dateAdded,
IF(COUNT(table2.table3Id) = COUNT(*), GROUP_CONCAT(table2.table3Id), NULL) as group1,
IF(COUNT(table3.ext) = COUNT(*), GROUP_CONCAT(table3.ext), NULL) as group2
FROM table1
LEFT JOIN table2 ON
table2.id = table1.table2Id
LEFT JOIN table3 ON
table3.id = table2.table3Id
Fixed it by changing
IF(COUNT(table3.ext) = COUNT(*), GROUP_CONCAT(table3.ext), NULL) as group2
to
GROUP_CONCAT(IFNULL(table3.ext, NULL)) as group2
In your situation when you are using joins use derieved sub query in join and use IFNULL and set its default value to 0 then in the outer table this value (0) will be used if there comes null.
EDITS :
as there is no data to test you can do it like this. Use INNER JOIN instead of left join.
SELECT
table1.table2Id,
table1.dateAdded,
IF(COUNT(table2.table3Id) = COUNT(*), GROUP_CONCAT(table2.table3Id), NULL) as group1,
IF(COUNT(table3.ext) = COUNT(*), GROUP_CONCAT(table3.ext), NULL) as group2
FROM table1
INNER JOIN table2 ON
table2.id = table1.table2Id
INNER JOIN table3 ON
table3.id = table2.table3Id
Also try using derieved sub query
SELECT
table1.table2Id,
table1.dateAdded,
IF(COUNT(t2.table3Id) = COUNT(*), GROUP_CONCAT(t2.table3Id), NULL) as group1,
IF(COUNT(table3.ext) = COUNT(*), GROUP_CONCAT(table3.ext), NULL) as group2
FROM table1
LEFT JOIN (
SELECT
id,
IFNULL(table3Id,0) as table3Id,
table3Id
FROM table2
GROUP BY id table3Id
)as t2 ON t2.id = table1.table2Id
INNER JOIN table3 ON table3.id = t2.table3Id
SELECT
count(t1.id) AS c1
FROM
table2
LEFT JOIN table1 AS t1 ON (t1.uid = table2.uid)
WHERE
table2.mode = 'ls'
GROUP BY
t1.id
c1 = 6 -> CORRECT!
SELECT
count(t2.id) AS c2
FROM
table2
LEFT JOIN table1 AS t2 ON (t2.pid = table2.id)
WHERE
table2.mode = 'ls'
GROUP BY
t1.id
c2 = 1 -> CORRECT!
SELECT
count(t1.id) AS c1,
count(t2.id) AS c2
FROM
table2
LEFT JOIN table1 AS t1 ON (t1.uid = table2.uid)
LEFT JOIN table1 AS t2 ON (t2.pid = table2.id)
WHERE
table2.mode = 'ls'
GROUP BY
t1.id
c1 = 6 -> CORRECT!
c2 = 6 -> WRONG!
How do I request both counts in one query, without getting wrong results?
I need to count two different requests at the same table (table1).
so, I'm using an alias for both request. (t1). Each alias-request is working fine alone. If I use both in the same query, i got wrong results.
count() will get you the number of records that are returned by your query. Since if you removed the counts and replaced it with * you would have 6 rows both of those counts are giving you 6.
Is there any reason why you cant use two sub selects and return the result of each of those?
So:
SELECT subQ1.c1, subQ2.c2 FROM
(SELECT count(t1.id) AS c1 FROM table2
LEFT JOIN table1 AS t1 ON (t1.uid = table2.uid)
WHERE table2.mode = 'ls') as subQ1,
(SELECT count(t2.id) AS c2 FROM table2
LEFT JOIN table1 AS t2 ON (t2.pid = table2.id)
WHERE table2.mode = 'ls') as SubQ2;
I believe your problem on the full query is your group by function. You are grouping by t.id, thus a1.id will have a different count based on how many rows you have.
What I mean by this is if there are 6 rows in table t, then count is going to return 6 for table t; but also since there looks to be a 1 to 1 relation on table a, there are 6 matching rows in table a to the 6 matching rows in table t. such that
t.id = a.id
1 = 1
2= 2 ...etc.
Thus your count is returning rows versus the count you believe you should have? I believe sum function is what you want to use here.
You could try this...but I'm not really sure what you're trying to do.
SELECT (...)
count(CASE WHEN t1.uid = t3.uid THEN t1.id ELSE NULL END) AS CBanz,
count(CASE WHEN ta1.pid = t3.id THEN a1.id ELSE NULL END) AS CBanz1
FROM
t0
LEFT JOIN (...)
LEFT JOIN t1 ON (t1.uid = t3.uid)
LEFT JOIN t1 AS a1 ON (a1.pid = t3.id)
WHERE (...)