SQL query want to eliminate the same data in multiple tables - php

**Table :1** **Table:2**
id folio num num1 num2 num3 num4 num5 id number folio
-------------------
------------------------------------------
1 abcde 1000 2000 3000 4000 5000 0 1 6000 abcde
2 1000 abcde
2 abcde 6000 3 7000 abcde
4 5000 abcde
5 10000 abcde
output want to be
id number folio
---------------
1 7000 abcde
2 10000 abcde
----------------------
I USED THE SQL QUERY OF
SELECT * FROM Table2 WHERE id_t = 'abcde'
AND number NOT IN(SELECT CONCAT(num,num1,num2,num3,num4,num5) FROM Table1 WHERE id_t = 'abcde')
-----------------------------------------------
SQL query want to eliminate the same data in multiple tables.
Want to compare two table but different fields ,if data in that table it want to eliminate only the unique data want to show
1.table2 number(field) want to check table1 num,num1,num2,num3,num4,num5(field)
2.values which was not in table 1 alone want to display

Doing a LEFT OUTER JOIN on a sub query. The sub query returns every num for each folio.
The WHERE clause then ensures only rows are returned where there is no match (ie, nothing matching found in the sub query).
SELECT Table2.id,
Table2.number,
Table2.folio
FROM Table2
LEFT OUTER JOIN
(
SELECT folio, num AS aNum FROM table1
UNION
SELECT folio, num1 AS aNum FROM table1
UNION
SELECT folio, num2 AS aNum FROM table1
UNION
SELECT folio, num3 AS aNum FROM table1
UNION
SELECT folio, num4 AS aNum FROM table1
UNION
SELECT folio, num5 AS aNum FROM table1
) sub0
ON Table2.folio = sub0.folio
AND Table2.number = sub0.num
WHERE sub0.folio IS NULL
Alternative that might make better use of index:-
SELECT Table2.id,
Table2.number,
Table2.folio
FROM Table2
LEFT OUTER JOIN table1 t1a ON Table2.folio = t1a.folio AND Table2.number = t1a.num
LEFT OUTER JOIN table1 t1b ON Table2.folio = t1b.folio AND Table2.number = t1b.num1
LEFT OUTER JOIN table1 t1c ON Table2.folio = t1c.folio AND Table2.number = t1c.num2
LEFT OUTER JOIN table1 t1d ON Table2.folio = t1d.folio AND Table2.number = t1d.num3
LEFT OUTER JOIN table1 t1e ON Table2.folio = t1e.folio AND Table2.number = t1e.num4
LEFT OUTER JOIN table1 t1f ON Table2.folio = t1f.folio AND Table2.number = t1f.num5
WHERE COALESCE(t1a.num, t1b.num1, t1c.num2, t1d.num3, t1e.num4, t1f.num5) IS NULL
EDIT
Another way to do it, although not keen on this one. Uses a sub query to concatenate up all the values of the various num fields, and then GROUP_CONCAT to do that over various lines. Then joins against that using FIND_IN_SET. Likely to be inefficient, but for amusement here it is:-
SELECT Table2.id,
Table2.number,
Table2.folio
FROM Table2
LEFT OUTER JOIN
(
SELECT folio, GROUP_CONCAT(CONCAT_WS(',', num, num1, num2, num3, num4, num5)) AS all_num
FROM table1
GROUP BY folio
) sub0
ON Table2.folio = sub0.folio
AND FIND_IN_SET(Table2.number, sub0.all_num) > 0
WHERE sub0.folio IS NULL

Related

MySQL Joins with "tolerance"

I would like to add some kind of "tolerance" to the following query. That means, that I can specify a value which expresses how many of the four (sub) selects return rows > 0. So if this value is 2, I only want to join these two tables. Is there a way to realize that?
SELECT distinct(user_id) FROM
(SELECT user_id FROM table1 WHERE ...) as t1
INNER JOIN
(SELECT user_id FROM table1 WHERE ...) as t2
ON t1.user_id=t2.user_id
INNER JOIN
(SELECT user_id FROM table1 WHERE ...) as t3
ON t1.user_id=t3.user_id
INNER JOIN
(SELECT user_id FROM table1 WHERE ...) as t4
ON t1.user_id=t4.user_id
EDIT:
Possible results for each sub-query could be as follows:
t1 t2 t3 t4
0 0 0
1 1 1 1
2 2 2 2
3 3
If all these sub results are joined it would result in: 1,2.
If I add a tolerance factor of 1, I want my result to be 0,1,2 as only one "0" is missing. If the factor was 2, the result would be 0,1,2,3 because two "3" and one "0" are missing. I hope this makes it clearer.
If i had understood your problem, you can add a variable in your sub-select and filter after:
SELECT distinct(user_id) FROM
(SELECT user_id, 1 as table_from FROM table1 WHERE ...) as t1
INNER JOIN
(SELECT user_id, 2 as table_from FROM table1 WHERE ...) as t2
ON t1.user_id=t2.user_id
INNER JOIN
(SELECT user_id, 3 as table_from FROM table1 WHERE ...) as t3
ON t1.user_id=t3.user_id
INNER JOIN
(SELECT user_id, 4 as table_from FROM table1 WHERE ...) as t4
ON t1.user_id=t4.user_id
WHERE table_from <= 2;
The solution was to union all sub selects and count them like follows:
SELECT distinct(user_id), sum(t) as tolerance FROM (
SELECT user_id, 1 as t FROM table1 WHERE ... GROUP BY...
UNION ALL
SELECT user_id, 1 as t FROM table1 WHERE ... GROUP BY...
UNION ALL
SELECT user_id, 1 as t FROM table1 WHERE ... GROUP BY...
UNION ALL
SELECT user_id, 1 as t FROM table1 WHERE ... GROUP BY...
) as x GROUP BY ... HAVING tolerance <= 2
Then you can specify how many sub selects should return something (here: 2).

SQL Join with subquery counting number of records with the same id in a different table

Okay so I have three(3) tables that i want to join together
tableA is the main details and primary key is row_id autoincremented
tableB is the exteded details and primary/foreign key is row_id coming from tableA
tableC stores unordered ratings and comments for a particular row_id
I want to join all these tables so that I can see all details plus the number of instances in tableC for a row_id and the avg rating.
SELECT *
FROM `tableA` A
LEFT JOIN `tableB` B
ON A.`row_id` = B.`row_id`
LEFT JOIN (
SELECT COUNT( 1 ) AS 'count', Avg(`row_rating`) AS 'avg'
FROM `tableC`
GROUP BY tableC.`row_id`
)C
ON C.`row_id` = A.`row_id`
ORDER BY C.`avg` ASC
The result of this query combines all properly but the same count and avg is displayed in all rows.
Looks like you want to group the records by row_id in inner query. In which case, you need to SELECT row_id instead of COUNT(1), try this:
SELECT *
FROM `tableA` A
LEFT JOIN `tableB` B
ON A.`row_id` = B.`row_id`
LEFT JOIN (
SELECT row_id, Avg(`row_rating`) AS 'avg'
FROM `tableC`
GROUP BY tableC.`row_id`
)C
ON C.`row_id` = A.`row_id`
ORDER BY C.`avg` ASC

MySQL union query, order by 2 variables

Each table (table1 & table2) has its own DATETIME field.
I'm trying to catch id's of the two tables and order them by their DATETIME field.
Example:
Table 1 Table 2
------------ -------------
id | datetime1 id | table1id | datetime2
------------------------ -----------------------
1 | 2014-09-21 20:31:26 1 | 2 | 2014-09-21 20:31:29
2 | 2014-09-21 20:31:27 2 | 3 | 2014-09-21 20:31:30
3 | 2014-09-21 20:31:28
Table 3
------------
id | user
------------------------
2 | phil
3 | nathalie
My output isn't ordered properly with this query:
SELECT *
FROM (
SELECT
1 AS selection,
table1.id, table1.datetime1,
table2.datetime2
table3.user
FROM Table1
LEFT OUTER JOIN table2
ON table1.id = table2.table1id
LEFT OUTER JOIN table3
ON table1.id = table3.id
UNION ALL
SELECT
2 AS selection,
table1.id, table1.datetime1,
table2.datetime2
table3.user
FROM Table1
INNER JOIN table2
ON table1.id = table2.table1id
INNER JOIN table3
ON table1.id = table3.id
) AS query
ORDER BY table1.datetime1 DESC, table2.datetime2 DESC
Desired data:
from table 2 id: 2, 1,
from table 1 id: 3, 2, 1
So: 2, 1, 3, 2, 1
////EDIT
To people who could be struggling with long and complex MySQL request, please try it in PhpmyAdmin! It will tell you the error!
////EDIT
What you really need to do is to consider your schema more carefully. Consider naming the date time columns the same and then running a query like this - http://sqlfiddle.com/#!2/a3b4c/7/0
SELECT selection, id, datetimefoo, user FROM (
SELECT
1 AS selection,
table1.id, table1.datetimefoo,
table3.user
FROM table1
LEFT OUTER JOIN table2
ON table1.id = table2.table1id
LEFT OUTER JOIN table3
ON table1.id = table3.id
UNION
SELECT
2 AS selection,
table1.id, table1.datetimefoo,
table3.user
FROM table1
INNER JOIN table2
ON table1.id = table2.table1id
INNER JOIN table3
ON table1.id = table3.id
) AS T2
ORDER BY datetimefoo DESC
In the SQL fiddle this produces the results closer to what you're looking for. I am still not sure why you need the INNER JOINS on the second query though - there is nothing that you're doing here whcih requires them.
Here is another method that does not require a changing of the column names, but requires an alias for the sortable columns - http://sqlfiddle.com/#!2/ec4bc/3/0
SELECT * FROM (
SELECT
1 AS selection,
table1.id, table1.datetimefoo AS sort_date, -- alias on first table's date
table2.datetimebar,
table3.user
FROM table1
LEFT OUTER JOIN table2
ON table1.id = table2.table1id
LEFT OUTER JOIN table3
ON table1.id = table3.id
UNION
SELECT
2 AS selection,
table1.id, table1.datetimefoo,
table2.datetimebar AS sort_date, -- alias on second table's date
table3.user
FROM table1
INNER JOIN table2
ON table1.id = table2.table1id
INNER JOIN table3
ON table1.id = table3.id
) AS T2
ORDER BY sort_date DESC
I believe you are over-complicating a rather straight-forward task:
SELECT *
FROM (
SELECT 1 AS selection, table1.id as id, table1.datetime1 as date FROM Table1
UNION ALL
SELECT 2 AS selection, table2.id as id, table2.datetime2 as date FROM Table2
) AS query
ORDER BY date DESC

MySQL Left join - no repeat for right side

I have
<table1>
column1 column2
1 A
2 B
2 C
<table2>
column3 column4
1 C
2 D
When I do left join
SELECT table1.column1,
table1.column2,
table2.column4
FROM table1
LEFT JOIN table2 ON table1.column1 = table2.column3
I get
column1 column2 column4
1 A C
2 B D
2 C D
Would it be possible to instead somehow get the output as,
column1 column2 column4
1 A C
2 B
2 C D
I want that for every repeated table1.column1, the table2.column4 should come only once and the remaining times it comes out blank.
I have tried various things but haven't succeeded in any.
give it a try
select
new_t1.column1, new_t1.column2, if(new_t1.get_value, t2.column4,'')
from
(select
t1.*, if(t1_tmp.column2 is null, 1, 0) as get_value
from table1 t1
left join table1 t1_tmp on t1.column1 = t1_tmp.column1 and t1.column2 < t1_tmp.column2
) as new_t1
left join table2 t2 on new_t1.column1 = t2.column3
Try this query:
select t4.column1,t4.column2,case when max2 is null
then null else t4.column4 end as column4 from
(select table1.column1, table1.column2, table2.column4,t3.* from table1
left join table2 on table1.column1 = table2.column3
left outer join
(select max2,max1 from
(select max(column2) max2,min(column2) min2,
max(column1) max1,min(column1) min1 from
(select table1.column1, table1.column2, table2.column4 from table1
left join table2 on table1.column1 = table2.column3)t1
group by column4)t2)t3
on table1.column1 = t3.max1 and table1.column2 = t3.max2)t4;
SQL Fiddle

MySQL Select Count with EXISTS

I have 3 tables.
table1
id, thing_id
table_index
id
table_index_info
table_index_id, table1_id
table_index_info contains a history of table_index. This history can refer to table1, possibly many times or 0 times.
I need to run a query that returns all rows in table1 with a specific thing_id.
It also needs to count how many rows in table_index that have at least 1 table_index_info linking to table1.
Here's my query:
SELECT table1.*,
(SELECT COUNT(i.id)
FROM table_index i
WHERE EXISTS (SELECT 0
FROM table_index_info h
WHERE h.table1_id = table1.id
AND h.table_index_id = i.id)
) AS indexCount
FROM table1
WHERE table1.thing_id= $thingId
Is this the best/correct way to do this?
I would use a JOIN instead of EXISTS in this case.
SELECT table1.*,
( SELECT COUNT(i.id)
FROM table_index i
INNER JOIN table_index_info h ON h.table_index_id = i.id
WHERE h.table1_id = table1.id
) AS indexCount
FROM table1
WHERE table1.thing_id = $thingId

Categories