Select tables that contain a specific value (Postgres) - database

in my DB there are more than 100 tables. Some of them have a column name "date".
I want to get all tables (table names) for a specific date.
so far I have been able to retrieve the table names that contain a date attribute:
SELECT pg_class.relname
FROM pg_class
INNER JOIN pg_attribute
ON pg_attribute.attrelid = pg_class.oid
WHERE pg_attribute.attname = 'date'
but I want to do somethin like that and it doesn´t work of course:
SELECT pg_class.relname
FROM pg_class
INNER JOIN pg_attribute
ON pg_attribute.attrelid = pg_class.oid
WHERE pg_attribute.attname = 'date'
AND date = '2014-12-05'

You can create a function that loops through the tables you've found and execute dynamically composed queries in it.
(Executing dynamic queries in PL/pgSQL)

Related

How to call an SQL Order Function from one table as reference to another?

I want to sort the column 'Name' from my table named 'People' using the SQL Order DESC referencing the column 'ReportID' in a separate table named 'Report' with the following execution:
cur.execute("""SELECT "Name" FROM People WHERE "ID" IN (SELECT "ID" FROM Report WHERE "ReportID" = ?) ORDER BY "Date" DESC""", (var,)
Instead, I get the error prompt:
sqlite3.OperationalError: no such column: Date
Any insights on what I can do to be able to call Date properly? Both tables are from the same database.
The column date is only visible inside the subquery of the operator IN.
Join the tables and then you can use the column date in the ORDER BY clause:
SELECT DISTINCT p.Name
FROM People p INNER JOIN Report r
ON r.ID = p.ID
WHERE r.ReportID = ?
ORDER BY r.Date DESC
You can remove DISTINCT if there is no case of duplicate matching rows in the table Report.

SQL: Building hierarchies and nesting queries on the same table

I am trying to build hierarchies by nesting queries on the same table in MS SQL Server 2014.
To give an example of what I am trying to achieve:
I have a table 'employees' whith the following columns:
[ID],[First Name],[Last Name],[ReportsTo]
{1},{John},{Doe},{2}
{2},{Mary},{Miller},{NULL}
I am trying to build a statement, where I join the employees table with itself and where I build a hierarchy with the boss on top.
Expected Result:
[Employee],[Boss]
{Miller,Mary},{NULL}
{Doe, John},{Miller,Mary}
I apologize, if this is a stupid question, but I fail to create a working nested query.
Could you please help me with that?
Thank you very much in advance
Based on the intended results, it looks like what you essentially want is a list of employees. So let's start with that:
SELECT LastName, FirstName, ReportsTo FROM Employees
This gives you the list, so you now have the objects you're looking for. But you need to fill out more data. You want to follow ReportsTo and show data from the record to which that points as well. This would be done exactly as it would if the foreign key pointed to a different table. (The only difference from being the same table is that you must use table aliases in the query, since you're including the same table twice.)
So let's start by joining the table:
SELECT e.LastName, e.FirstName, e.ReportsTo
FROM Employees e
LEFT OUTER JOIN Employees b on e.ReportsTo = b.ID
The results should still be the same, but now you have more data to select from. So you can add the new columns to the SELECT clause:
SELECT
e.LastName AS EmployeeLastName,
e.FirstName AS EmployeeFirstName,
b.LastName AS BossLastName,
b.FirstName AS BossFirstName
FROM Employees e
LEFT OUTER JOIN Employees b on e.ReportsTo = b.ID
It's a join like any other, it just happens to be a join to the same table.

Need query to determine number of attachments for each issue

I have a database in SQL Server that has three tables: Issues, Attachments, and Requestors. I need a single query that returns all the columns contained in the "Issues" and "Attachments" tables. Listed below is the query that I've created, but it's not working as expected:
SELECT A.*,
B.*,
SubQuery.attachmentcount
FROM [DB].[dbo].[issues] AS A
FULL OUTER JOIN [DB].[dbo].[requestors] AS B
ON A.issue_id = B.issue_id,
(SELECT Count(attachments.attachment_id) AS AttachmentCount
FROM issues
LEFT OUTER JOIN attachments
ON issues.issue_id = attachments.issue_id
WHERE attachments.attachment_status = 1
GROUP BY issues.issue_id) AS SubQuery;
Pictures describing the three tables are listed below:
Any ideas on how to fix my query?
Thanks,
"I need a single query that returns all the columns contained in the "Issues" and "Attachments" tables".
Based on this sentence try this:
SELECT A.Issue_ID, I.Issue_Name,r.Name, COUNT(A.attachment_id) AS Count
FROM Attachments as A
INNER JOIN Issues I on I.issue_id = A.issue_id
INNER JOIN requestors as R on A.issue_id = R.requestor_id
WHERE A.attachment_status = 1
GROUP BY A.Issue_ID, I.Issue_Name, r.Name
--Specify all columns by name (don't use *)
Keep It Simple and Try This!
SELECT i.Issue_ID, i.Issue_Name, COUNT(a.attachment_id) AS AttachmentCount
FROM attachments a JOIN
issues i ON
i.issue_id = a.issue_id
WHERE a.attachment_status = 1
GROUP BY i.Issue_ID, i.Issue_Name
Add your Desired Columns in Both Select List and Group By Clause and you are done.

Select value from different tables based on the column value in SQL Server

I have a main table A with the following fields:
Then I have three separate tables, each for Buildings, Classrooms and Offices. All these tables have two columns; ID and Name.
I want to query the table A to get the following result:
How can I do this?
Your data isn't really normalized. Having three separate tables all serving the same lookup is causing you some headache... so I unioned the 3 tables together and created a 'src' column so you could join table A's type and Id back to table B's ID and src. You'd have been better off having one table and non-repeating IDs and a type ID to specify if it's a building classroom or office.
Select *
from A
LEFT JOIN (SELECT 'Building' as src, ID, Name FROM Buildings UNION ALL
SELECT 'Classroom' as src, ID, Name FROM Classrooms UNION ALL
SELECT 'Office' as src, ID, Name FROM Offices) B
on A.Location_Type = B.Src
and A.LocationID = B.ID
I used a left join here in case not all records in A have an associated record in B. However, an inner join should work as well.
Should be doable with the use of a join.
Something along those lines should work:
SELECT tabelA.ID, tabelA.Subject, tabelA.Date, tabelA.locationType, tabelB.location
FROM tabelA INNER JOIN tabelB on tabelA.locationID = tabelB.locationID

Copy one table into another fails - "Column names in each table must be unique"

When I try this:
SELECT *
-- INTO DB2.dbo.CustomerOrderLines
FROM DB1.dbo.CustomerOrderLines
INNER JOIN DB1.dbo.CustomerOrders ON DB1.dbo.CustomerOrders.Order_Display_Ref = DB1.dbo.CustomerOrderLines.Order_Display_Ref
WHERE DB1.dbo.CustomerOrders.Delivered_Date BETWEEN '2009-09-23' and '2009-09-24'
it show the rows correctly.
When I try to copy the contents from one table in DB1 into the same table in DB2 (and create it if it does not exist):
SELECT *
INTO DB2.dbo.CustomerOrderLines
FROM DB1.dbo.CustomerOrderLines
INNER JOIN DB1.dbo.CustomerOrders ON DB1.dbo.CustomerOrders.Order_Display_Ref = DB1.dbo.CustomerOrderLines.Order_Display_Ref
WHERE DB1.dbo.CustomerOrders.Delivered_Date BETWEEN '2009-09-23' and '2009-09-24'
it fails with
Msg 2705, Level 16, State 3, Line 1
Column names in each table must be unique. Column name 'Order_Display_Ref' in table 'CustomerOrderLines' is specified more than once.
SELECT * INTO and INSERT INTO SELECT * work fine when copying other tables from one database into another, but they do not use JOINS.
What is my mistake?
You want to add the content of the DB1.dbo.CustomerOrderLines to DB2.dbo.CustomerOrderLines?
Then, tell SQL Server in your SELECT that you want only the content of this table.
SELECT DB1.dbo.CustomerOrderLines.*
INTO DB2.dbo.CustomerOrderLines
FROM DB1.dbo.CustomerOrderLines
INNER JOIN DB1.dbo.CustomerOrders ON DB1.dbo.CustomerOrders.Order_Display_Ref = DB1.dbo.CustomerOrderLines.Order_Display_Ref
WHERE DB1.dbo.CustomerOrders.Delivered_Date BETWEEN '2009-09-23' and '2009-09-24'
You are joining two tables together which both have this Order_Display_Ref column in it. It looks like you only want the data from CustomerOrderLines so I would do :
SELECT DB1.dbo.CustomerOrderLines.*
INTO DB2.dbo.CustomerOrderLines
FROM DB1.dbo.CustomerOrderLines
INNER JOIN DB1.dbo.CustomerOrders ON DB1.dbo.CustomerOrders.Order_Display_Ref = DB1.dbo.CustomerOrderLines.Order_Display_Ref
WHERE DB1.dbo.CustomerOrders.Delivered_Date BETWEEN '2009-09-23' and '2009-09-24'
It seems that CustomerOrderLines and CustomerOrders have one or more columns where the name is the same, e.g. CustomerOrderLines.Id and CustomerOrders.Id would cause this kind of clash as your query would attempt to create two columns both called Id.
note : at least one of your problems is coming from the column Order_Display_Ref, which appears in both these tables. There may be more.
Both tables on DB1 have the Order_Display_Refcolumn, so it's trying to insert it twice. Simply supply a column list rather than * and it should work fine.
You are joining DB1 table to itself and selecting all resulting columns. This will mean all column names are duplicated.
You need to specify the source you are inserting from:
SELECT DB1a.*
INTO DB2.dbo.CustomerOrderLines
FROM DB1.dbo.CustomerOrderLines DB1a
INNER JOIN DB1.dbo.CustomerOrders DB1b
ON DB1.dbo.CustomerOrders.Order_Display_Ref = DB1.dbo.CustomerOrderLines.Order_Display_Ref
WHERE DB1.dbo.CustomerOrders.Delivered_Date BETWEEN '2009-09-23' and '2009-09-24'
Or simply rename the column(s) having the same name.
SELECT
TableA.Column1,
TableA.Column1,
TableA.Column2,
TableA.Order_Display_Ref,
TableB.Order_Display_Ref as TableBOrder_Display_Ref,
TableB.ColumnN
INTO DB2.dbo.CustomerOrderLines
FROM DB1.dbo.CustomerOrderLines
INNER JOIN DB1.dbo.CustomerOrders
ON DB1.dbo.CustomerOrders.Order_Display_Ref = DB1.dbo.CustomerOrderLines.Order_Display_Ref
WHERE DB1.dbo.CustomerOrders.Delivered_Date BETWEEN '2009-09-23' and '2009-09-24'

Resources