I'm writing MySQL to get all unique IDs from all tables in a database.
The database has tables like record_20181201, record_20181202, ...
The tables are automatically generated based on date (all tables have the same schema, and one column name is visitorId).
The SQL query I made is like,
SELECT UNIQUE(visitorId) FROM databaseName.record_20181201;
I can only query one table at a time using this..
Is there a way to query all tables in the database and select all unique visitorIds there?
SELECT DISTINCT VisitorID FROM DBName.Table1
UNION
SELECT DISTINCT VisitorID FROM DBName.Table2
UNION
SELECT DISTINCT VisitorID FROM DBName.Table3
Try this!!!!!!Hope this helps..
You could generate a query string with UNION's from the INFORMATION_SCHEMA.
Then run that query, or put it in a view.
A UNION will return a unique combined result of the unioned queries.
While a UNION ALL would just stick the results together.
SELECT GROUP_CONCAT(Qry ORDER BY TblSchema, TblName SEPARATOR ' UNION ')
FROM
(
SELECT
TABLE_SCHEMA as TblSchema,
TABLE_NAME as TblName,
CONCAT('select visitorId from ',TABLE_SCHEMA,'.',TABLE_NAME,'\r\n') as Qry
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE 'record_201812%'
AND COLUMN_NAME = 'visitorId'
) Q;
Run below query you will get a single query that will give unique visitorId from all table.
SELECT
CONCAT('SELECT DISTINCT visitorId FROM (',
REPLACE(query_string, ',', ' UNION '),
') union_table') AS final_query
FROM
(SELECT
CONCAT(GROUP_CONCAT('SELECT visitorId FROM ', table_name)) AS query_string
FROM
information_schema.tables
WHERE
table_name LIKE 'record_%') table_a;
you will get below query that will fetch unique visitorId from all tables.
SELECT DISTINCT
visitorId
FROM
(
SELECT visitorId FROM record_20181201
UNION
SELECT visitorId FROM record_20181202
UNION
SELECT visitorId FROM record_20181203
) union_table
Related
How do you run an "order by" and then "replace" string, but keep the order? Context - I need the string "column_name" to be in the first line, hence using "zzz_column_name" to force it in the order by. And then I need to use replace to change it from "zzz_column_naem" to "column_name".
SELECT replace(column_name, 'zzz_', '')
FROM (
SELECT *
FROM (
SELECT 'zzz_column_name' AS column_name
UNION
SELECT column_name
FROM table
) s
ORDER BY column_name DESC
) a
After the replace in the first line, I'd lose the order achieved by order by.
Just order by the unmodified column. You don't even need a subquery:
SELECT replace(column_name, 'string', '') AS column_name_replaced
FROM (
SELECT 'zzz_column_name' AS column_name
UNION ALL
SELECT column_name FROM table
) s
ORDER BY column_name DESC
Note: UNION ALL is more efficient than UNION - use it unless you have good reasons not to
I am wondering if you are actually trying to put first the row that has the fixed value; in that case, we can simplify the whole thing with just a conditional sort. Assuming a table like mytable(col), we can add a header row with value 'my_header' like so:
SELECT 'my_header' AS col, 1 AS is_header
UNION ALL
SELECT col, 0 FROM mytable
ORDER BY is_header DESC, col
This puts the header row first, followed by all values in order.
If you mind the additional column, we can remove it with a subquery:
SELECT col
FROM (
SELECT 'my_header' AS col, 1 AS is_header
UNION ALL
SELECT col, 0 FROM mytable
) t
ORDER BY is_header DESC, col
You don't need the outer SELECT and you can sort by the original column name
SELECT replace(column_name, 'string', '')
FROM (
SELECT 'zzz_column_name' AS column_name
UNION
SELECT column_name
FROM table
) s
ORDER BY column_name DESC
I have the table in mysql with records:
I've written the sql query:
SELECT COUNT(*) AS number_of_contacts, channel_id, direction
FROM cic_case_contacts
WHERE case_id = 328678
GROUP BY channel_id, direction
and the result looks like:
I would like to obtain something like below(based on above data):
I was trying to obtaining that with sql query by using my_sql_function GROUP_CONCAT but it dosen't work:
SELECT COUNT(*) AS number_of_contacts, channel_id, GROUP_CONCAT(direction SEPARATOR ', ') AS directions
FROM cic_case_contacts
WHERE case_id = 328678 AND id IN(149196, 149195, 149194, 149193, 149192) AND `office_id` = 10
GROUP BY channel_id
ORDER BY channel_id
I would be greateful for help.
You can use GROUP_CONCAT on a sub query as follows:
SELECT channelid, GROUP_CONCAT(
CONCAT(direction, ': ', c)
ORDER BY direction
SEPARATOR ', '
) AS summary
FROM (
SELECT channelid, direction, COUNT(*) AS c
FROM t
GROUP BY channelid, direction
) x
GROUP BY channelid
Or simply use conditional aggregation:
SELECT channelid, CONCAT_WS(', ',
CONCAT('in: ', COUNT(CASE WHEN direction = 'in' THEN 1 END)),
CONCAT('out: ', COUNT(CASE WHEN direction = 'out' THEN 1 END))
) AS summary
FROM t
GROUP BY channelid
You can use Concat in MySQL
drop table if exists Demo;
CREATE TABLE Demo
(
ID INT AUTO_INCREMENT PRIMARY KEY,
channelid int,
Name VARCHAR(20)
);
INSERT INTO Demo(channelid, Name)VALUES
(1,'in'),(1,'out'),(1,'in'),(1,'out'),(2,'in'),(2,'out'),(1,'in'),(1,'out'),(1,'in'),(2,'out'),(2,'in'),(2,'out'),(2,'in'),(1,'in'),(1,'in');
Query
SELECT SQL_CALC_FOUND_ROWS
channelid,
group_concat ( concat(name,':',channelid) )
FROM Demo
group by channelid;
SELECT FOUND_ROWS();
See the results the the fiddle
Please find below working code as per your requirement :
select tb.channelid, group_concat
(
concat(tb.name,':',tb.MyCol2Count)
) as v1
from
(Select tbl.channelid,tbl.name,(LENGTH(tbl.val) - LENGTH(REPLACE(tbl.val,",","")) + 1) AS MyCol2Count
from
(SELECT channelid, group_concat
(
concat(name,':',channelid)
) as val,name
FROM Demo
group by channelid,Name) as tbl) as tb group by tb.channelid
You can check on below screenshot : http://springinfosoft.com/code/Groupby_code.png
I was thinking about proper database design while going through some databases where out of 150,000 records some columns had only 5-20 values set. It got me thinking that columns with low utilization should be transferred to a pivot table and was hoping to run a report that would tell me which to evaluate.
I tried a foreach, but it isn't working for me. Any tips?
foreach('SELECT table_name,
column_name
FROM information_schema.columns
WHERE table_schema = "mydb"',
'SELECT ${2}, utilization
FROM mydb.${1}.${2}
LEFT JOIN
(
SELECT sum(secondary_email)/count(*) AS utilization
FROM (
SELECT
CASE
WHEN secondary_email IS NULL THEN 0
ELSE 1
END AS secondary_email
FROM offices ) AS c )
GROUP BY ${2} ')
I was hoping for a better answer, feel free to out do me here. Copy and paste the output here and remove the final UNION ALL
SELECT
CONCAT('SELECT ', QUOTE(tb), ', ',QUOTE(col),', sum(`has_value`)/count(*) AS utilization FROM (SELECT CASE WHEN `',col,'` IS NULL THEN 0 ELSE 1 END AS has_value FROM ',tb,' ) AS c UNION ALL') SearchSQL
FROM
(
SELECT table_schema db,table_name tb,column_name col FROM information_schema.columns
WHERE table_schema = 'myDB' AND
(column_type LIKE 'char(%' OR column_type LIKE 'varchar(%' OR column_type LIKE '%text')
) A
I would like to get string sum check "column 1".
Do you have idea how to do it?
jack, john, bill, joe, sindy
Something similar to
=JOIN(Fields!Column1.Value, ",")
SAMPLE TABLE
CREATE TABLE #TEMP(COLUMN1 VARCHAR(100),COLUMN2 VARCHAR(100))
INSERT INTO #TEMP
SELECT 'jack',1
UNION ALL
SELECT 'john',1
UNION ALL
SELECT 'bill',1
UNION ALL
SELECT 'joe',1
UNION ALL
SELECT 'sindy',1
QUERY
If you need the value with comma separate values and count, you can avoid query before UNION ALL and execute the query only after UNION ALL.
SELECT NULL,COLUMN1,COLUMN2
FROM #TEMP
UNION ALL
SELECT DISTINCT 'TOTAL',
-- Here we convert to comma separated values
SUBSTRING(
(SELECT ', ' + COLUMN1
FROM #TEMP T2
--WHERE C2.Id=Id AND C2.COLUM=COLUM
FOR XML PATH('')),2,200000) COLUMN1,
COUNT(COLUMN1) COLUMN2
FROM #TEMP T1
I have a query similar to this:
select 'table_1', count(*)
from table_1
union
select 'table_2', count(*)
from table_2
union
select 'table_n', count(*)
from table_n
returning the total of rows for each table (n tables).
table_1 | 100
table_2 | 150
table_n | 400
I want to know if there is a mysql function that can just add a new record at the end making the sum of all rows like this:
table_1 | 100
table_2 | 150
table_n | 400
total | 650
Is there a way to do that in mySQL (version 5.5) whithout using a procedure?
(for exemple using a variable inside the sql if supported)
select ifnull(table_name,'Total'), sum(row_count)
from (select 'table_1' table_name, count(*) row_count
from table_1
union
select 'table_2' table_name, count(*) row_count
from table_2
union
select 'table_n' table_name, count(*) row_count
from table_n ) temp
group by table_name with rollup;
Maybe use WITH ROLLUP:-
SELECT TableName, TableCount
FROM
(
SELECT 'table_1' AS TableName, COUNT(*) AS TableCount
FROM table_1
union
SELECT 'table_2' AS TableName, COUNT(*) AS TableCount
FROM table_2
SELECT
select 'table_n' AS TableName, COUNT(*) AS TableCount
FROM table_n
) Sub1
GROUP BY TableName, TableCount WITH ROLLUP
If you are only after the the number of rows, you should use the system table.
This will have the advantage that if you are preparing the query you don't have to hard code the table names as these can be passed as parameters:
select ifnull(table_name,'Total') as table_name, sum(table_rows) as table_rows
from (
SELECT
TABLE_NAME,
TABLE_ROWS
FROM
INFORMATION_SCHEMA.TABLES
WHERE
TABLE_NAME IN ('tOne', 'tTwo', 'tThree')
) temp
group by table_name with rollup;
select 'table_1', count(*)
from table_1
union
select 'table_2', count(*)
from table_2
union
select 'table_n', count(*)
from table_n
union
select 'total', sum(a.count)
from (
select 'table_1', count(*)
from table_1
union
select 'table_2', count(*)
from table_2
union
select 'table_n', count(*)
from table_n
) a