I would like to create a table that populates its data from other tables through SQL queries. For example:
Create TABLE1 with columns (AVERAGE_ROWS int, AVERAGE_RATING int)
Insert into TABLE1 values (SELECT COUNT(*) FROM TABLE X, SELECT AVG(rating) FROM TABLE X)
Insert into TABLE1 values (SELECT COUNT(*) FROM TABLE Y, SELECT AVG(rating) FROM TABLE Y)
Is this possible?
Thanks in advance, el retardo.
You will need to follow the format:
INSERT INTO table2 (column_name(s))
SELECT column_name(s) FROM table1;
So in your case it would look something like (SQL Fiddle):
INSERT INTO TABLE1 (AVERAGE_ROWS, AVERAGE_RATING)
SELECT COUNT(*), AVG(rating) FROM X
UNION
SELECT COUNT(*), AVG(rating) FROM Y;
As you can see in the example you are going to lose your presion on AVG(rating) since AVERAGE_RATING is declared as int. You would be better off using decimal(,) instead. Something like SQL Fiddle.
Related
How can I select which table each result is from, when I use a UNION command to search multiple tables?
For example, if there are results from both tables, how can I add a column that will say (or differentiate between) whether it is from tableA or tableB.
try this one, simply add a virtual column for the name of the table.
SELECT *
FROM
(
SELECT *, 'tableA' as tableName FROM tableA
UNION ALL
SELECT *, 'tableB' as tableName FROM tableB
UNION ALL
SELECT *, 'tableC' as tableName FROM tableC
) s
WHERE colName = 'hello'
I got a database named accounts and account table inside of this database, Also I got the database named players and player table inside of this database.
How can I get a rows count of this two tables in one query?
I've tried this:
SELECT
SUM(`account`.`account`.`id`) AS 'accounts',
SUM(`player`.`player`) AS 'players';
But it doesn't work.
If you need exactly rows count (not sum), than do something like this:
select
(select count(*) from accounts.account) as count1,
(select count(*) from players.player) as count2
or
select count(*) as `count`,"account" as `table` from accounts.account
union all
select count(*) as `count`,"player" as `table` from players.player
A simple UNION operation on two select statements will do:
SELECT COUNT(*), 'Accounts' FROM Accounts.Account
UNION
SELECT COUNT(*), 'Players' FROM Players.Player
And you have to qualify each table with the database name since they're in separate databases.
Try:
SELECT
COUNT(`account`.`id`) AS 'accounts',
COUNT(`player`.`player`) AS 'players'
FROM
`account`,
`player`
SELECT COUNT(*)
FROM (
SELECT Id
FROM accounts.account
UNION ALL
SELECT player
FROM players.player ) AS BothTables
with Value (nbr, name ) as
(
select count(*) amount, 'AccountsCount' as ab from accounts..account
union all
select count(*) amount, 'PlayersCount' as ab from players..player
)
select *
from value as s
PIVOT(sum(nbr) for name in (AccountsCount, PlayersCount) ) as pvt
i've a problem for a table update. follow table structure:
Table1
tableid
...
...
productID_1
productID_2
productID_3
Table2
productID
Total
I've to totalize each product in table2.
For example:
SELECT COUNT(*) as tot, ProductID_1 FROM Table1 GROUP Table1
then the UPDATE table2 SET total =..??? (how can i do) WHERE productID_1 = ....
Hope you can help me.
Thank you
Your options in terms of simplifying the query greatly depend on the product and version you are using. However, a solution that should work in most databases would be:
Update Table2
Set Total = (
Select Count(*)
From (
Select productId_1 As ProductId From Table1
Union All Select productId_2 From Table1
Union All Select productId_3 From Table1
) As Z
Where Table2.ProductId = Z.ProductId
Group By ProductId
)
A big reason this query is cumbersome is that the data in Table1 is not normalized. Instead you should consider a structure for Table1 like:
Create Table Table1 (
TableId <datatype> not null
, ProductId <datatype> not null
, Constraint PK_Table1 Primary Key ( TableId, ProductId )
)
You can store the first results in a temp table/table variable (if the DB you are using supports it). For instance, in SQL Server, you can do:
declare #t table
(
key int,
cnt int
)
insert into #t (key, cnt)
select count(*) as tot, ProductID_1 from Table1 ...
If ProductID_2 and ProductID_3 are in the same table, you can union the results.
Then, insert into table 2:
insert into table2 (productID, Count)
select key, cnt from #t
REPLACE INTO table2
SELECT COUNT(*) as total, ProductID
FROM Table1
GROUP Table1.ProductID
I'd like to do an insert select where the select statement has aggregate columns for use by a "HAVING" clause, but where I do not actually want those columns to be inserted. A simple example:
INSERT INTO table1 ( a )
SELECT a, MAX (b) AS maxb FROM table2
GROUP BY a
HAVING maxb = 1
Of course, this won't work because there are a different number of columns in the INSERT and the SELECT. Is there as simple way to make this work? I was hoping I could define some sort of null column in the INSERT field list, or something. I was hoping to avoid a subquery in my SELECT statement, although I could probably do it that way if necessary.
INSERT INTO table1 ( a )
SELECT a FROM (SELECT a, MAX (b) AS maxb FROM table2
GROUP BY a
HAVING maxb = 1) t
You can rewrite the query like this
INSERT INTO table1 ( a )
SELECT a FROM table2
GROUP BY a
HAVING MAX (b) = 1
I have a MySQL query where I have a nested SELECT that returns an array to the parent:
SELECT ...
FROM ...
WHERE ... IN (SELECT .... etc)
I would like to store the number of returned results (row count) from the nested SELECT, but doing something like IN (SELECT count(...), columnA) does not work, as the IN expects just one result.
Is there a way to store the returned result count for later use within the parent statement?
You're probably going to have to select the results of your nested statement into a temporary table. Then you can do an IN and a count on it later. I'm more familiar with MS-SQL, but I think you should be able to do it like this:
CREATE TEMPORARY TABLE tmp_table AS
SELECT something
FROM your_table;
SELECT ...
FROM ...
WHERE ... IN (SELECT * FROM tmp_table);
SELECT count(*) FROM tmp_table;
If that doesn't work, you may have to provide full details to the temporary table creation statement as you would with a normal "CREATE TABLE". See here in the MySQL manual, and here for a similar example.
CREATE TEMPORARY TABLE tmp_table
(
tableid INT,
somedata VARCHAR(50)
);
INSERT INTO tmp_table
SELECT ...
FROM ...
SELECT ...
FROM ...
WHERE ... IN (SELECT * FROM tmp_table);
SELECT count(*) FROM tmp_table;
Rich
You mentioned in your comment that your query look like this:
SELECT
tabA.colA,
tabA.colB
FROM tabA
WHERE tabA.colA IN ( SELECT tabA.colA FROM tabA WHERE tabA.colB = 1 )
I might be missing something, but you don't need a subquery for this. Why don't you do it in a regular where condition:
SELECT
tabA.colA,
tabA.colB,
FROM tabA
WHERE tabA.colB = 1
You can use IN predicate for multiple columns like this:
SELECT *
FROM table
WHERE (col1, col2) IN
(
SELECT col3, col4
FROM othertable
)
If you want to select COUNT(*) along with each value, use this:
SELECT colA, colB, cnt
FROM (
SELECT COUNT(*) AS cnt
FROM tabA
WHERE colB = 1
) q,
tabA
WHERE colB = 1