How to get row count on multiple schemas with same table name - sql

There are many schemas and each schema has users table. I use different schemas for each organization/tenant. I want to get users count with COUNT function. How can I do that on all schemas?
i.e
schamas = [org1,org2,org3]
org1.tables = (users,videos,pictures)
org2.tables = (users,videos,pictures)
org3.tables = (users,videos,pictures)
What I tried
select count(users) from *.users;

Use scalar sub-queries. Using union CTEs for users, videos and pictures or PL/pgSQL are possible alternatives. Please note that the query below - not a very smart one indeed nor very efficient - has a regular structure and could be built mechanically by using a template.
select
(select count(*) from org1.users) +
(select count(*) from org2.users) +
(select count(*) from org3.users) as userscnt,
(select count(*) from org1.videos) +
(select count(*) from org2.videos) +
(select count(*) from org3.videos) as videoscnt,
(select count(*) from org1.pictures) +
(select count(*) from org2.pictures) +
(select count(*) from org3.pictures) as picturescnt;

Related

Merging two query results in a materialized view

Im trying to merge two SELECT results into one view.
The first query returns the id's of all registered users.
The second query goes through an entire table and counts how many victories a player has and returns the id of the player and number of wins.
What I'm trying to do now is to merge these two results, so that if the user has wins it states how many but if he doesn't then it says 0.
I tried doing it like this:
SELECT profile.user_id
FROM profile
FULL JOIN ( SELECT player_game_data.user_id,
count(player_game_data.user_id) AS wins
FROM player_game_data
WHERE player_game_data.is_winner = 1
GROUP BY player_game_data.user_id) t2 ON profile.user_id::text = t2.user_id::text;
But in the end it only returns id's of the players and there isn't a count column:
What am I doing wrong?
Is this what you want?
select p.*,
(select count(*)
from player_game_data pg
where pg.user_id = p.user_id and pg.is_winner = 1
) as num_wins
from profile p;
Or, if all users have played at least one game, you can use conditional aggregation:
select pg.user_id,
count(*) filter (where pg.is_winner = 1)
from player_game_data pg
group by pg.user_id;
Or, if is_winner only takes on the values of 0 and 1:
select pg.user_id, sum(ps.is_winner)
from player_game_data pg
group by pg.user_id;
Thanks for the help Gordon. I've got it to work now.
The final query looks like this :
SELECT p.user_id,
( SELECT count(*) AS count
FROM player_game_data pg
WHERE pg.user_id::text = p.user_id::text AND pg.is_winner = 1) AS wins,
( SELECT count(*) AS count
FROM player_game_data pg
WHERE pg.user_id::text = p.user_id::text AND pg.is_winner = 0) AS losses,
( SELECT count(*) AS count
FROM player_game_data pg
WHERE pg.user_id::text = p.user_id::text) AS games_played
FROM profile p;
And when I run it I get the result that i wanted:

Oracle - return only the first row for each product

In the first SELECT statement, the report grabs inv details for all products with shipment activity. There is then a UNION that connect another SELECT statement to grab products without activity from the last calendar year.
However, the records that are returned in the second SELECT statement have multiple header_id’s and therefore multiple lines… instead of single lines like the first SELECT statement. Do you know how to pull only the first header_id of each record in the second SELECT statement?
Code and example result set below. In data, product #7 should only list the row for header_id 1372288 which is the last ID entered into the DB.
select 3 sort_key, header_Id,location_id,nlasinv.product,
start_inv,produced produced_inv,stored,from_stock,shipped,
(start_inv + produced + stored) - (from_stock + shipped) end_inv,nlas_ops_mtd_prodsize(111,nlasinv.product,'31-DEC-19'), nlas_ops_mtd_shipsize(111,nlasinv.product,'31-DEC-19'),nlas_ops_ytd_prodsize(111,nlasinv.product,'31-DEC-19'), nlas_ops_ytd_shipsize(111,nlasinv.product,'31-DEC-19')
from nlas_header inv,
nlas_inventory nlasinv
where nlasinv.header_id = 1372168
and inv.id = nlasinv.header_id
union
select distinct
3 sort_key,header_Id,location_id,nlasinv.product,
start_inv,produced produced_inv,stored,from_stock,shipped,
(start_inv + produced + stored) - (from_stock + shipped) end_inv,nlas_ops_mtd_prodsize(111,nlasinv.product,'31-DEC-19'),
nlas_ops_mtd_shipsize(111,nlasinv.product,'31-DEC-19'),nlas_ops_ytd_prodsize(111,nlasinv.product,'31-DEC-19'),
nlas_ops_ytd_shipsize(111,nlasinv.product,'31-DEC-19')
from
nlas_inventory nlasinv,
nlas_header hdr
where
nlasinv.header_id = hdr.id
and hdr.location_id = 409
and hdr.observation_date >= trunc(to_date('31-DEC-19','dd-mon-rr'),'year')
and nlasinv.product not in
(select distinct product from
nlas_header h,
nlas_inventory i
where i.header_id = 1372168)
order by product, header_id des
c
I don't know what your query has to do with the "table" data that you show. But you seem to want row_number():
select t.*
from (select t.*, row_number() over (partition by product order by header_id desc) as seqnum
from t
) t
where seqnum = 1;
If that query is being used to generate the data, then just wrap it in a CTE.
This can also be accomplished by adding a self join in your where clause
and hdr.header_id = (
select max(hdr2.header_id)
from nlas_header hdr2
where hdr2.location_id = hdr.location_id
and hdr2.product_id = hdr.product_id)

SQL Views (id + count_table1_column1 + count_table2_column_1)

Im doing following query to select out a serialnumber from table Alerts, and then count how many alerts there is for that serialnumber together with the count on how many measurements there also is for that serialnumber. Measurements is stored in another table. (first 2 queries is jsut there to show you the result for better understanding)
SELECT InstrumentSerialNumber FROM [dbo].[CloudMeasurements]
SELECT InstrumentSerialNumber FROM [dbo].[CloudAlerts]
SELECT
DISTINCT InstrumentSerialNumber,
(SELECT COUNT(*) FROM [CloudAlerts] WHERE [CloudAlerts].InstrumentSerialNumber = InstrumentSerialNumber) AS Alerts,
(SELECT COUNT(*) FROM [CloudMeasurements] WHERE [CloudMeasurements].InstrumentSerialNumber = InstrumentSerialNumber) AS Measurements
FROM [CloudAlerts]
Result
See picture for result of the query.
I assume it respond with Count(*) summarized which makes it wrong from my perspective. How do I write this?
Greetings
Try joining the results of their groups:
SELECT
A.InstrumentSerialNumber,
A.TotalAlerts,
ISNULL(M.TotalMeasurements, 0) TotalMeasurements
FROM
(SELECT InstrumentSerialNumber, COUNT(*) TotalAlerts FROM [CloudAlerts] GROUP BY InstrumentSerialNumber) AS A
LEFT JOIN (SELECT InstrumentSerialNumber, COUNT(*) TotalMeasurements FROM [CloudMeasurements] GROUP BY InstrumentSerialNumber)
AS M ON M.InstrumentSerialNumber = A.InstrumentSerialNumber

SQL Logic: Finding Non-Duplicates with Similar Rows

I'll do my best to summarize what I am having trouble with. I never used much SQL until recently.
Currently I am using SQL Server 2012 at work and have been tasked with trying to find oddities in SQL tables. Specifically, the tables contain similar information regarding servers. Kind of meta, I know. So they each share a column called "DB_NAME". After that, there are no similar columns. So I need to compare Table A and Table B and produce a list of records (servers) where a server is NOT listed in BOTH Table A and B. Additionally, this query is being ran against an exception list. I'm not 100% sure of the logic to best handle this. And while I would love to get something "extremely efficient", I am more-so looking at something that just plain works at the time being.
SELECT *
FROM (SELECT
UPPER(ta.DB_NAME) AS [DB_Name]
FROM
[CMS].[dbo].[TABLE_A] AS ta
UNION
SELECT
UPPER(tb.DB_NAME) AS [DB_Name]
FROM
[CMS].[dbo].[TABLE_B] as tb
) AS SQLresults
WHERE NOT EXISTS (
SELECT *
FROM
[CMS].[dbo].[TABLE_C_EXCEPTIONS] as tc
WHERE
SQLresults.[DB_Name] = tc.DB_NAME)
ORDER BY SQLresults.[DB_Name]
One method uses union all and aggregation:
select ab.*
from ((select upper(name) as name, 'A' as which
from CMS.dbo.TABLE_A
) union all
(select upper(name), 'B' as which
from CMS.dbo.TABLE_B
)
) ab
where not exists (select 1
from CMS.dbo.TABLE_C_EXCEPTION e
where upper(e.name) = ab.name
)
having count(distinct which) <> 2;
SQL Server is case-insensitive by default. I left the upper()s in the query in case your installation is case sensitive.
Here is another option using EXCEPT. I added a group by in each half of the union because it was not clear in your original post if DB_NAME is unique in your tables.
select DatabaseName
from
(
SELECT UPPER(ta.DB_NAME) AS DatabaseName
FROM [CMS].[dbo].[TABLE_A] AS ta
GROUP BY UPPER(ta.DB_NAME)
UNION ALL
SELECT UPPER(tb.DB_NAME) AS DatabaseName
FROM [CMS].[dbo].[TABLE_B] as tb
GROUP BY UPPER(tb.DB_NAME)
) x
group by DatabaseName
having count(*) < 2
EXCEPT
(
select DN_Name
from CMS.dbo.TABLE_C_EXCEPTION
)

Determine active rows from multiple tables and place in a Variable Table

I have to determine how many rows are active from each Table. Then return the answers in one query AND put the results in a Table Variable.
a. Path
b. Course
c. Section
d. Event
I was able to determine the active rows with the following query:
SELECT * FROM [dbo].[ADF_Path]
WHERE PathActive is NULL
SELECT * FROM [dbo].[ADF_Course]
WHERE CourseActive = '1'OR
CourseActive = 'y'
SELECT * FROM [dbo].[ADF_Event]
WHERE EventActive = 'y'
Is it POSSIBLE to join these tables in order to arrive at the same conclusion
OR
How do I determine the active rows in 1 query?
Placing the query in a Variable Table is not a problem. I just need to know
how to formulate the query. (See Tables below)
Thank You
do you want something like?:
SELECT count(*) as cnt FROM [dbo].[ADF_Path] WHERE PathActive is NULL
union all
SELECT count(*) FROM [dbo].[ADF_Course] WHERE CourseActive = '1' OR CourseActive = 'y'
union all
SELECT count(*) FROM [dbo].[ADF_Event] WHERE EventActive = 'y'
you can also add column to distinguish between different counts, or summarize them like:
select sum(cnt) from ( <union query from above> ) as t