union all two table but diff number of column - mysql

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'
)

Related

How to count occurrences with derived tables in SQL?

I have this very simple table:
CREATE TABLE MyTable
(
Id INT(6) PRIMARY KEY,
Name VARCHAR(200) /* NOT UNIQUE */
);
If I want the Name(s) that is(are) the most frequent and the corresponding count(s), I can neither do this
SELECT Name, total
FROM table2
WHERE total = (SELECT MAX(total) FROM (SELECT Name, COUNT(*) AS total
FROM MyTable GROUP BY Name) table2);
nor this
SELECT Name, total
FROM (SELECT Name, COUNT(*) AS total FROM MyTable GROUP BY Name) table1
WHERE total = (SELECT MAX(total) FROM table1);
Also, (let's say the maximum count is 4) in the second proposition, if I replace the third line by
WHERE total = 4;
it works.
Why is that so?
Thanks a lot
You can try the following:
WITH stats as
(
SELECT Name
,COUNT(id) as count_ids
FROM MyTable
GROUP BY Name
)
SELECT Name
,count_ids
FROM
(
SELECT Name
,count_ids
,RANK() OVER(ORDER BY count_ids DESC) as rank_ -- this ranks all names
FROM stats
) s
WHERE rank_ = 1 -- the most popular ```
This should work in TSQL.
Your queries can't be executed because "total" is no column in your table. It's not sufficient to have it within a sub query, you also have to make sure the sub query will be executed, produces the desired result and then you can use this.
You should also consider to use a window function like proposed in Dimi's answer.
The advantage of such a function is that it can be much easier to read.
But you need to be careful since such functions often differ depending on the DB type.
If you want to go your way with a sub query, you can do something like this:
SELECT name, COUNT(name) AS total FROM myTable
GROUP BY name
HAVING COUNT(name) =
(SELECT MAX(sub.total) AS highestCount FROM
(SELECT Name, COUNT(*) AS total
FROM MyTable GROUP BY Name) sub);
I created a fiddle example which shows both queries mentioned here will produce the same and correct result:
db<>fiddle

FULL TEXT only select if at least X words match

SELECT source, id
FROM memory_row
WHERE memory_id =10
AND MATCH(source)
AGAINST ('girl*, appears*, cool*, pragmatic*, things*, first*, glance*, actually*, warm*,
trusting*, created*, Design*, Children*, Togetsu*, existed*, solely*, activate*, Strings*,
experienced*, emotional*, damage*, young*, from*, experiments*, conducted*, her*, cruel*,
researchers*, sent*, Randall*, family*, treatment*, after*, sealing*, memories*, small*, world*,
older*, adoptive*, sister*, Naomi*')
The above query returns results in which only a few words match. I want to only return results that contain at least X of the terms that are being matched against. In the example above, that number can be 10. That means that the column must contain at least 10 fulltext matches to be returned.
How can I do this?
EDIT
One answer suggested the following. I get an error, "Incorrect arguments to AGAINST".
select m.*
from memory_row m
where
memory_id = 10
and (
select count(*)
from (
select 'girl*' word
union all select 'appears*'
union all select 'actually*'
union all select 'girl*'
union all select 'cool*'
union all select 'pragmatic*'
union all select 'things*'
union all select 'first*'
union all select 'glance*'
union all select 'actually*'
) w
where match(m.source) against(w.word)
) >= 5
I am unsure that there is an easy way to do what you want. You might need to enumerate the values as rows, and then use a correlated subquery to compute the count of matches:
select m.*
from memory_row m
where
memory_id = 10
and (
select count(*)
from (
select 'girl*' word
union all select 'appears*'
...
) w
where match(m.source) against(w.word)
) >= ?
Where the qestion mark represents the minimum number of rows that should match.
Or, in very recent versions of MySQL:
select m.*
from memory_row m
where
memory_id = 10
and (
select count(*)
from (values row('girl*'), row('appears*'), ...) w(word)
where match(m.source) against(w.word)
) >= ?
One method is to use match to get an initial set of documents. And then additional logic afterwards:
SELECT mr.*
FROM (SELECT source, id
FROM memory_row
WHERE memory_id = 10 AND
MATCH(source) AGAINST ('girl*, appears*, cool*, pragmatic*, things*, first*, glance*, actually*, warm*,
trusting*, created*, Design*, Children*, Togetsu*, existed*, solely*, activate*, Strings*,
experienced*, emotional*, damage*, young*, from*, experiments*, conducted*, her*, cruel*,
researchers*, sent*, Randall*, family*, treatment*, after*, sealing*, memories*, small*, world*,
older*, adoptive*, sister*, Naomi*')
) mr
WHERE ( (source like '%girl%') +
(source like '%actually%') +
. . .
) >= 10;
Note: This is not exactly the same logic, because it is just looking for strings. If you want more precise logic, you can use regular expressions, but that might not be necessary.

How to count the total number of results before a hyphen?

I am looking to count the number of results from a SQL count query, the results currently have like 50 results, but in reality there are only 5 results... the results appear in a format such as:
test1-helpme1
test1-helpme3
test1-helpme4
test2-helpme1
test2-helpme2
test3-helpme4
Is there a way I can count just the "testx-" part of the results?
There can be hundreds of results so the number part of "test" can't be hardcoded
SELECT COUNT(*) as CountbyID, OriginalId FROM Table1 GROUP BY OriginalId;
If you want the number of the distinct occurrences of the pattern, then:
SELECT
COUNT(DISTINCT LEFT(OriginalId, INSTR(OriginalId, '-') - 1)) as counter
FROM Table1
or a counter for each one:
SELECT
LEFT(OriginalId, INSTR(OriginalId, '-') - 1) pattern,
COUNT(*) as counter
FROM Table1
GROUP BY LEFT(OriginalId, INSTR(OriginalId, '-') - 1)
Yup you can use LEFT to group by a subset of the string:
declare #test as table (test varchar(100))
insert into #test
Select 'test1-helpme1' UNION ALL
Select 'test1-helpme3' UNION ALL
Select 'test1-helpme4' UNION ALL
Select 'test2-helpme1' UNION ALL
Select 'test2-helpme4'
Select count(*) as countbyID, left(test,5) as originalid from #test group by left(test,5)

Return Year-Value that occurs more than once in two columns

I would like to select all number of years that occur more than once in between two columns.
Here is what I have so far:
SELECT YEAR(`Date1`), COUNT(*) as Counter
from (SELECT YEAR(`Date1`)
from table1 UNION
SELECT YEAR(`date2`)
from table1
) as year
GROUP by YEAR(`date1`)
WHERE Counter > 2;
I appreciate any advice!
Thanks.
When you are using GROUP BY , you need to use HAVING not WHERE like following.
SELECT Y ,
COUNT(*) AS Counter
FROM (
SELECT DISTINCT YEAR(`Date1`) Y
FROM table1
UNION ALL
SELECT DISTINCT YEAR(`date2`) Y
FROM table1) AS YEAR
GROUP BY Y
HAVING COUNT(*) > 2;
Note: You don't need to put YEAR again in your outer query, also you can put DISTINCT, for each column so that you don't get duplicates for the column.
I think your problem is the UNION. It needs to be UNION ALL, or you will never find duplicates.
Then, you can simply do:
SELECT yyyy, COUNT(*) as Counter
FROM (SELECT YEAR(`Date1`) as yyyy
FROM table1
UNION ALL
SELECT YEAR(`date2`) as yyyy
FROM table1
) y
GROUP BY yyyy
HAVING Counter >= 2;
Note the changes to the query:
UNION ALL instead of UNION so the subquery does not eliminate duplicates.
Giving a column alias to the year, in this case, yyyy.
Using the column alias in the outer query.
Using HAVING instead of WHERE.

MySQL: check that a set of queries returns the same row count : : but I don't know what the count is

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