I have this query to search in two SQL tables. I am looking for a way to sort the result by occurrence. This is my query:
SELECT `parent_id`
FROM wp_forum_posts
WHERE text LIKE '%{$term1}%'
UNION
SELECT `id`
FROM wp_forum_threads
WHERE subject LIKE '%{$term1}%
Which is the best way, to get the results ordered?
The trick is first to use UNION ALL, which preserves duplicates (ordinary UNION removes duplicates), then select from that result. This query should do it:
select * from (
select parent_id as mID, count(*) as cnt
from wp_forum_posts
where text like '%{$term1}%'
group by 1
UNION ALL
select id, count(*)
FROM wp_forum_threads
where subject like '%{$term1}%
group by 1) x
order by 2, 1
Assumes ID and parent_ID are not duplicates in tables otherwise you can get 2 rows per an id... and would you want them summed together if so then are parent_ID and ID related?
Select mID, cnt
FROM
(SELECT `parent_id` as mID, count(`parent_ID`) as cnt
FROM wp_forum_posts
WHERE text LIKE '%{$term1}%'
Group by `parent_ID`
UNION
SELECT `id`, count(`id`) as cnt
FROM wp_forum_threads
WHERE subject LIKE '%{$term1}%
GROUP BY `id`)
Order by cnt ASC, mID
Related
I have 3 tables with a common 'type_id' column. its a foreign key from Table_type
Table_1 id,type_id,date...
Table_2 id,type_id,date...
Table_3 id,type_id,date...
Table_Type id, type_name, description
select type_id, count(*) from Table_1 GROUP BY type_id
gives the count from individual table.
i want to know how many times is a particular type used.
type_id, count(from 3 tables)
1 , 10
2 , 5
3 . , 3
Use union all and group by:
select type_id, count(*)
from ((select type_id from table_1) union all
(select type_id from table_2) union all
(select type_id from table_3)
) t
group by type_id
Get the counts from each table, combine those queries with UNION, and add up the counts.
SELECT type_id, SUM(count)
FROM (
SELECT type_id, COUNT(*) AS count
FROM table_1
UNION ALL
SELECT type_id, COUNT(*) AS count
FROM table_2
UNION ALL
SELECT type_id, COUNT(*) AS count
FROM table_3
) AS x
GROUP BY type_id
If there are indexes on the type_id column, this query should be able to take advantage of them. And the UNION processes smaller tables because it combines after the grouping.
I have basic table looking like:
When I am using the Query:
SELECT *, SUM(cr) AS cr, SUM(dr) AS dr FROM my_table GROUP BY id
I am getting:
and that's correct!
What's the proper query to get (each sum in different row):
I already tried GROUP BY ID,CR,DR and GROUP BY CR,DR,ID but with not the results that I wanted. (I don't care if the 0 values are also NULL)
You can do:
select id, sum(dr) as dr, 0 as cr from my_table group by id
union all
select id, 0, sum(cr) from my_table group by id
order by id, dr desc
Let's consider a made up example
SELECT id, name, score.score FROM
someTable,
(select someTableId, count(*) as score FROM SecondTable GROUP BY someTableId) as score
WHERE score.someTableId == id
ORDER BY score.score DESC
Let's now assume that I have a backend computing my scoring, and that I would like to remove the subquery and insert my own data instead. I would like to know how to do this.
I would like to do something like (this is the question, because what's below doesn't work):
SELECT id, name, score.score FROM
someTable,
((12,324), (1, 342)) as score(id, score)
WHERE score.someTableId == id
ORDER BY score.score DESC
Here is an example of external data substitution to a subquery:
SELECT * FROM users WHERE id IN (SELECT user_id FROM posts WHERE thread_id = 12 GROUP BY user_id);
Without a subquery and with external data:
SELECT * FROM users WHERE id IN (1,2,3);
If I understood you correctly :
SELECT id, name, score.score FROM
someTable,
(SELECT 12 as someTableId,324 as score UNION ALL SELECT 1, 342 <UNION ALL....>) as score(id, score)
WHERE score.someTableId == id
ORDER BY score.score DESC
Thats the only way you can do it, it doesn't actually replace the the subquery, but it replace the select from the table and can improve performance if thats what you are looking for.
In MySQL you don't need to specify a from clause like a dummy table when you are just looking to fetch dummy data.
Other DBMS require a dummy table name (typically DUAL) but in MySQL it's rather straightforward:
SELECT 12 AS id, 324 AS score
UNION ALL SELECT 2, 65
UNION ALL SELECT 3, 598
UNION ALL SELECT 4, 244
You can use this as any other result-set.
select count(*) as total FROM ( SELECT * FROM database1.orders WHERE number LIKE "11111111111111111" UNION ALL SELECT * FROM database2.orders WHERE number LIKE "11111111111111111" ) AS b
but i got error :
The used SELECT statements have a different number of columns
because run SELECT * FROM database2.orders WHERE number LIKE "11111111111111111" give me a result is null.
How to merge it with a query because with a query to help me process the pagination
Thank for helps !
Just do the aggregation before the union all:
select sum(cnt) as total
FROM ((SELECT count(*) as cnt
FROM database1.orders
WHERE number LIKE '11111111111111111'
)
UNION ALL
(SELECT count(*) as cnt
FROM database2.orders
WHERE number LIKE '11111111111111111'
)
) t;
Note I changed the string delimiter to be a single quote rather than a double quote. It is good practice to use single quotes for string and date constants (and nothing else).
By the way, you can also do this using a join:
select o1.cnt1, o2.cnt1, (o1.cnt1 + o2.cnt1) as total
FROM (SELECT count(*) as cnt1
FROM database1.orders
WHERE number LIKE '11111111111111111'
) o1 cross join
(SELECT count(*) as cnt2
FROM database2.orders
WHERE number LIKE '11111111111111111'
) o2;
This makes it easier to get the individual counts for the two databases.
The orders table in database1 probably has a different number of columns than the table by the same name in database2.
Instead of using select *, select the columns you're interested in, like select userid, productid, deliveryaddress, .... Make sure you specify the same columns in both parts of the union.
For a count(*), you could choose no columns at all, and select the value 1 for each row, like:
select count(*)
from (
select 1
from database1.orders
where number like '111'
union all
select 1
from database2.orders
where number like '111'
) as SubQueryAlias
Or you can add the result of two subqueries without a union:
select (
select count(*)
from database1.orders
where number like '111'
)
+
(
select count(*)
from database2.orders
where number like '111'
)
We read values from a set of sensors, occasionally a reading or two is lost for a particular sensor , so now and again I run a query to see if all sensors have the same record count.
GROUP BY sensor_id HAVING COUNT(*) != xxx;
So I run a query once to visually get a value of xxx and then run it again to see if any vary.
But is there any clever way of doing this automatically in a single query?
You could do:
HAVING COUNT(*) != (SELECT MAX(count) FROM (
SELECT COUNT(*) AS count FROM my_table GROUP BY sensor_id
) t)
Or else group again by the count in each group (and ignore the first result):
SELECT count, GROUP_CONCAT(sensor_id) AS sensors
FROM (
SELECT sensor_id, COUNT(*) AS count FROM my_table GROUP BY sensor_id
) t
GROUP BY count
ORDER BY count DESC
LIMIT 1, 18446744073709551615
SELECT sensor_id,COUNT(*) AS count
FROM table
GROUP BY sensor_id
ORDER BY count
Will show a list of the sensor_id along with a count of all the records it has, you can then manually check to see if any vary.
SELECT * FROM (
SELECT sensor_id,COUNT(*) AS count
FROM table
GROUP BY sensor_id
) AS t1
GROUP BY count
Will show all the counts that vary, but the group by will lose information about which sensor_ids have which counts.
---EDIT---
Taken a bit from both mine and eggyal's answer and created this, for the count that is most frequent I call the id default, and then for any values that stand out I have given them separate rows. This way you maintain the readability of a table if you have many results Multi Row, but also have a simple one row column if all counts are the same One Row. If however you are happy with the concocted strings then go with eggyal's answer.
Might be a bit over the top but here goes:
select 'default' as id,t5.c1 as count from(
select id,count(*) as c1 from your_table group by id having count(*)=
(select t4.count from
(
select max(t3.count2) as max,t3.count as count from
(
select count(*) as count2,t2.count from
(
SELECT id,COUNT(*) AS count
FROM your_table
GROUP BY id
) as t2
GROUP BY count
) as t3
) as t4)) as t5 group by count
union all
select t5.id as id,t5.c1 as count from(
select id,count(*) as c1 from your_table group by id having count(*)<>
(select t4.count from
(
select max(t3.count2) as max,t3.count as count from
(
select count(*) as count2,t2.count from
(
SELECT id,COUNT(*) AS count
FROM your_table
GROUP BY id
) as t2
GROUP BY count
) as t3
) as t4)) as t5