nested select query with table name in sqlite - sql

I am trying to select all distinct values from all tables that start with a specific name, like: 'logs_2020_12_01', 'logs_2021_01_02', ..To select all tables with this specific name is straight forward:
SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'logs_%';
The select I want for one individual table is:
SELECT DISTINCT batch FROM logs_2021_01_27;
but I cannot find a way to combine it to make the selection from all tables. I tried a couple of things but it does not work, like:
SELECT DISTINCT batch FROM (SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'logs_%')
any ideas?
thanks

What about using Dynamic SQL, stored your tables information into a temp table with id column and set it to identity.
CREATE TABLE #temp ---identity column will be used to iterate
(
id INT IDENTITY,
TableName VARCHAR(20)
)
INSERT INTO #temp
SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'logs_%';
-- choose your own results with where conditions
DECLARE #SQL VARCHAR(MAX)
DECLARE #Count INT = 1
DECLARE #Table VARCHAR(20)
WHILE #COUNT <= (SELECT COUNT(*) FROM #temp)
BEGIN
select #table = TABLENAME FROM #temp WHERE id = #Count
SELECT #sql = 'SELECT DISTINCT(batch) FROM '+ #table
PRINT #SQL
SET #Count = #Count + 1
END
after your print result looks good, change it to EXEC(#SQL), thanks

SQLite does not support dynamic sql.
You have to select the column batch from each of all the tables and combine them with UNION so the duplicates are removed:
SELECT batch FROM logs_2020_12_01 UNION
SELECT batch FROM logs_2020_12_02 UNION
......................................
SELECT batch FROM logs_2020_12_30 UNION
SELECT batch FROM logs_2020_12_31
If you don't know the full names of the tables, you can get them with this statement:
SELECT name
FROM sqlite_master
WHERE type = 'table' AND name LIKE 'logs/_%' ESCAPE '/'
and then use a programming language to construct a SELECT statement with UNION to get the results that you want.

Related

SQL Server run SELECT for each in list

I won't be surprised if SQL just doesn't work this way at all, but:
If we run two SELECT statements in a query, we get a split "Results" pane. I'm wondering if I can add variables to a list, and then have the number of result pane splits match the length of that list.
If I were to mix languages:
id_list = [26275, 54374, 84567]
for i in id_list:
SELECT * FROM table WHERE id = i
I'm just trying to easily compare results of a query while keeping distinct groups, with a changing number of variables. Since loops never seem to be the answer in SQL, I'd be just as happy inserting something like a blank line or horizontal rule, etc. Not sure if that's possible either though...
There is no concept of "lists" (as a separate data structure) in T-SQL. Does this do what you want?
SELECT *
FROM table
WHERE id IN (26275, 54374, 84567);
declare #i int = 0;
declare #Id int;
declare #Ids table (Id int);
insert #Ids select Id from (values (26275), (54374), (84567)) t(Id);
-- OR: insert #Ids select * from string_split('26275, 54374, 84567', ',');
declare #Count int = (select count(*) from #Ids);
while #i < #Count
begin
select #Id = Id, #i = #i + 1
from #Ids order by Id
offset #i rows fetch next 1 rows only;
select * from dbo.MyTable where Id = #Id;
end
You can use UNION ALL:
SELECT * FROM table WHERE id = 26275
UNION ALL
SELECT * FROM table WHERE id = 54374
UNION ALL
SELECT * FROM table WHERE id = 84567

Store value from SELECT statement into variable on SQL Server

I am trying to select value from the system object,synonyms and then store into #variable. Then I can select data from #variable without caring the server.
However it keeps saying that I need to declare scalar variable. Can anyone help?
DECLARE #variable NVARCHAR(100)
SELECT #variable = name
FROM sys.synonyms
WHERE base_object_name = '[ABC].[dbo].[tblABC]'
SELECT * FROM #variable
Your query selects all names and successively stores them in the variable, meaning that each name overwrites the previously stored name, so only the last selected name is available in the variable when the SELECT statement terminates. If you want a variable that you can query like a temporary table, you will have to declare a table variable and insert the names into that "table", afterwards you can run a select statement against that variable:
Declare #variable table (name nvarchar(128));
INSERT INTO #variable (name)
SELECT name
FROM sys.synonyms
where base_object_name = '[ABC].[dbo].[tblABC]';
select * from #variable;
But: Also on this query, the server will "care".
The problem is that you need to return only one value to the variable. In this way:
Declare #variable nvarchar(100)
#variable = (SELECT TOP(1) name -- getting only one registry
FROM sys.synonyms where base_object_name =
'[ABC].[dbo].[tblABC]')
select #variable
You have to do next :
declare #names table ( name nvarchar(100 ) );
insert #names(name)
select name
FROM sys.synonyms
where base_object_name = '[ABC].[dbo].[tblABC]';
select * from #names

Nested update SQL Server and SELECT

I need to have a query as below:
SELECT top (1) #AddressRepeatNum=a.CheckNumber FROM(
UPDATE dbo.SearchList SET CheckNumber=CheckNumber+1
OUTPUT inserted.CheckNumber AS CheckNumber
WHERE PageAddress=#Address and CheckNumber<6
) as a
but it doesn't work. How should I rewrite it to work?
In a simple word, I want to add one to a column of my table and then if it was larger than 5 then do something
You cannot do a select directly on an update like that. You insert the output information to a table variable and then you select from the table variable.
DECLARE #AddressRepeatNum INT, #Address varchar (500) = 'Test'
DECLARE #Check table (checknumber INT)
UPDATE dbo.SearchList SET CheckNumber=CheckNumber+1
OUTPUT inserted.CheckNumber into #Check
WHERE PageAddress=#Address and CheckNumber<6
SELECT TOP (1) #AddressRepeatNum=CheckNumber
FROM #check
ORDER BY CheckNumber

TSQL Subquery for Column Names?

Is it possible to use a set of query results for column names in a select statement?
Example, I have a table named TableA:
Column: Type:
KeyOne nvarchar(5)
KeyTwo nvarchar(5)
TableB is another table, whose column names might be stored in TableA.
Suppose TableB is like this:
Column: Type:
Val1 int
Val2 int
Is there any way I could do a query like this to get the columns?
SELECT (select TOP 1 KeyOne, KeyTwo FROM TableA)
FROM TableB
Another example using strings would be like this:
SELECT (select 'Val1', 'Val2')
FROM TableB
Is this possible in any way without concatenated SQL?
Unfortunately you can only do this with dynamic SQL, but it's pretty straightforward:
DECLARE #cols VARCHAR(MAX) = (SELECT TOP 1 KeyOne+','+KeyTwo FROM TableA)
,#sql VARCHAR(MAX)
SET #sql = 'SELECT '+#cols+' FROM TableB'
EXEC (#sql)
You can read table column names dynamically from sys.columns system views or using other management views
select name from sys.columns where object_id = object_id(N'TableName')
Then by creating a dynamic SQL query you can create your own select

How can I perform this query?

One of the fields in my database is a string containing multiple usernames separated by commas (ex: 'wasingej, doej, hamm, ..."). I want to do a query where a database entry (or multiple) is selected if a supplied username appears in the string containing multiple usernames.
How would I do this?
The best I could come up with is
CREATE TABLE supportContacts
(
id int identity primary key,
usernames varchar(255),
);
INSERT INTO supportContacts
(usernames)
VALUES
('Dan'),
('DAN,SCOTT'),
('Jordan,Michael,Dan'),
('Adam,Kelly,Daniel,Roger,Sue'),
('Crystal,Kari,Logan,Daniella'),
('Jon,Dan,Xerxes,Brian'),
('Samantha,Keylin,Dan')
;
SELECT * from supportContacts WHERE
usernames = 'Dan' or -- only dan
usernames LIKE 'Dan,%' or -- begins
usernames LIKE ',Dan,' or -- within
usernames LIKE '%,Dan' -- ends
It has the problem that it doesn't match on case - not an issue if your input isn't case sensitive anyway - but it is Better than Raging Bull's answer because it doesn't match the names within other names ( my fiddle shows this by not matching 'Daniella' or 'Daniel' )
http://sqlfiddle.com/#!6/72493/4
USING LIKE:
DECLARE #CONDITION VARCHAR(255)
SET #CONDITION = '%'' UNION SELECT * FROM TableName WHERE ColName LIKE ''%'
DECLARE #Unames VARCHAR(255) --List of username you pass from your program
SET #Unames = 'wasingej,doej,hamm' --Taking it as an example
DECLARE #FullQuery VARCHAR(255)
SET #FullQuery = 'SELECT *
FROM TableName
WHERE ColName LIKE ''%'+REPLACE(#Unames,',',#CONDITION)+'%''' --Replacing comma with #Condition
EXEC(#FullQuery)
At last, you can get your query in the variable #FullQuery like this:
SELECT * FROM TableName WHERE ColName LIKE '%wasingej%'
UNION
SELECT * FROM TableName WHERE ColName LIKE '%doej%'
UNION
SELECT * FROM TableName WHERE ColName LIKE '%hamm%'
See example in SQL Fiddle.