Is there a way to get the current table data is fetched from?
Maybe easier to give an example:
Select
current server -> Returns "PDBS" or whatever
, current table(a) -> Is there something similar that would return "customer"?
, a.customer_no
, b.order_no
from customer a
left join orders b
on b.customer_no = a.customer_no
where
customer_no = 123456
;
Edit:
The reason I'm asking is that we have a number of tables (20ish) with descriptions for different things with language support. We have 3 test environments and production and I've written a script that identifies discrepancies in the environments.
I have hardcoded the table names and in doing so was curious if there was a way to extract the table names directly...
Related
For reasons that I will not tell you not to bore .. I need to directly access the database to extract the notes Feature. So I create this script to identify the projects i'm interested
SELECT *
FROM [Tfs_GedCollection].[dbo].[tbl_WorkItemCoreLatest] a
INNER JOIN [Tfs_GedCollection].[dbo].[tbl_WorkItemCustomLatest] b ON a.PartitionId=b.PartitionId AND a.DataspaceId=b.DataspaceId AND a.Id = b.Id
where a.[WorkItemType] = 'Feature'
AND b.FieldId IN (
-- CAMPO CODICEMMA
SELECT [FieldId] FROM [Tfs_GedCollection].[dbo].[tbl_Field]
where [Tfs_GedCollection].[dbo].[tbl_Field].[Name] = 'CODICEMMA'-- Filed for identify projects in my company
)
But I miss the last step: obtain the history (the discussion that is inserted through the control with type = WorkItemLogControl (mapped with the fieldname = System.History).
Thanks in advance
It's not suggest to query the original database and also highly not recommend to modify the database data in TFS.
However, you can query for historical data about features, tasks, and other types of work items by using FactWorkItemHistory and the associated dimension tables shows in TFS data warehouse. More details please refer Work Item History tables
Another way is using TFS API to achieve this. How to achieve it please have a look at: TFS SDK: Work Item History Visualizer using TFS API
I find the information that i need on the view: [vw_WorkItemComments] (in the column named [Text]).
So the query will be:
-- Identificazione dei progetti
SELECT b.stringvalue, c.[System.CreatedBy_IdentityDisplayPart], c.[System.ChangedDate], c.[Text]--, *
FROM [Tfs_GedCollection].[dbo].[tbl_WorkItemCoreLatest] a
INNER JOIN [Tfs_GedCollection].[dbo].[tbl_WorkItemCustomLatest] b ON a.PartitionId=b.PartitionId AND a.DataspaceId=b.DataspaceId AND a.Id = b.Id
INNER JOIN [Tfs_GedCollection].[dbo].[vw_WorkItemComments] c ON a.Id = c.[System.Id]
where a.[WorkItemType] = 'Feature'
AND b.FieldId IN (
-- CAMPO CODICEMMA
SELECT [FieldId] FROM [Tfs_GedCollection].[dbo].[tbl_Field]
where [Tfs_GedCollection].[dbo].[tbl_Field].[Name] = 'CODICEMMA'-- Filed for identify projects in my company
)
I have 3 tables that I wish to UPDATE data against (lets call them PROCESS, DIARY and HISTORY)
The 3 tables all have an ID column and the subset of data I wish to update is retrieved from a SELECT statement against the PROCESS table
SELECT ID FROM PROCESS WHERE STATUS = 1 AND COMPANY = 'XYZ'
Using T-SQL, I was planning to do 3 UPDATE statements (with the PROCESS table being last as it is the reference list) like so
UPDATE HISTORY ... WHERE ID IN (SELECT ID FROM PROCESS WHERE STATUS = 1 AND COMPANY = 'XYZ')
UPDATE DIARY ... WHERE ID IN (SELECT ID FROM PROCESS WHERE STATUS = 1 AND COMPANY = 'XYZ'
)
UPDATE PROCESS ... WHERE STATUS = 1 AND COMPANY = 'XYZ'
My question is: is this the most efficient way to do this within T-SQL - or should I be creating some sort of CTE to reference only once? (The number of documents/performance are not a problem, I'm just trying to find out if as an ex OO developer coming to SQL, I'm slipping into bad habits or missing a trick somewhere
I don't think you will be able to use CTE as CTE can be referenced only once. Updating 3 tables requires 3 separate queries to be run.
If obtaining the ID's in your inner query is expensive, you may consider running the query to get them only once and storing the results in a temporary table or table variable. This way you will be able to reference that temporary table or table variable in all update statements.
If the inner query is inexpensive to run, I would leave it as is to not complicate things unnecessarily.
--Query1
SELECT TransactionDetails.Transactions.TransactionId
, TransactionDetails.Transactions.CustomerId
, TransactionDetails.Transactions.TransactionType
, TransactionDetails.Transactions.DateEntered
, TransactionDetails.Transactions.RelatedProductId
, CustomerDetails.CustomerProducts.CustomerFinancialProductId
, CustomerDetails.CustomerProducts.CustomerId AS 'CustomerProducts--CustomerID'
, CustomerDetails.CustomerProducts.FinancialProductId
, CustomerDetails.CustomerProducts.AmountToCollect
FROM TransactionDetails.Transactions
INNER JOIN CustomerDetails.Customers ON TransactionDetails.Transactions.CustomerId = CustomerDetails.Customers.CustomerID
INNER JOIN CustomerDetails.CustomerProducts ON CustomerDetails.Customers.CustomerID = CustomerDetails.CustomerProducts.CustomerId
WHERE TransactionId = 2
ORDER BY CustomerFinancialProductId
--Query2
SELECT TransactionDetails.Transactions.TransactionId
, TransactionDetails.Transactions.CustomerId
, TransactionDetails.Transactions.TransactionType
, TransactionDetails.Transactions.DateEntered
, TransactionDetails.Transactions.RelatedProductId
, CustomerDetails.CustomerProducts.CustomerFinancialProductId
, CustomerDetails.CustomerProducts.CustomerId AS 'CustomerProducts--CustomerID'
, CustomerDetails.CustomerProducts.FinancialProductId
, CustomerDetails.CustomerProducts.AmountToCollect
FROM TransactionDetails.Transactions
INNER JOIN CustomerDetails.FinancialProducts ON TransactionDetails.Transactions.RelatedProductId = CustomerDetails.FinancialProducts.ProductId
INNER JOIN CustomerDetails.CustomerProducts ON CustomerDetails.FinancialProducts.ProductId = CustomerDetails.CustomerProducts.FinancialProductId
WHERE TransactionId = 2
ORDER BY CustomerFinancialProductId
Here are two queries that i have been given to compare. it asks which one navigates better ir should be the correct one used?
I know that the first query returns only 1 row where as the second returns 11 rows.
Also Query 1 navigates through Transactions to Customers where it's using ProductID as it's column in each. the 2nd query goes from Transactions to FinancialProducts where the join is on RelatedProductID in the transactions table and productID in the FinancialProducts table
Both queries then end in the same table with the same columns chosen in that table.
Lastly the FinancialProductID is 22 in the first query and in the 2nd query all 11 rows have a financialProductID of 22
ACTUAL QUESTION: WHICH ONE IS THE CORRECT FORM OF NAVIGATING TO THE TABLE
The question that you have asked is a business question about the meaning of the data.
It looks like both versions of the query are properly joining the tables together. You understand your business domain, whereas the rest of us do not.
That said, based on the names of the tables, the first version "makes sense" to me. A transaction has a customer and customers have products. So, if you want all the products for a customer on a transaction, then the first would seem to do that.
I don't know what role FinancialProducts plays in this database. It is quite possible that the second version "makes more sense" for this application. If you are using this database, you should learn what these tables are.
Hi am I am creating a database which allows users to make a reservation to a restaurant. Below is my data model for the database.
My question is i am a little confused with how i would check for tables that are available on a given night. The restaurant has 15 tables for any night with 4 people to a table (Groups can be 4 - 6 big, groups larger than 4 will take up two tables).
How would i query the database to return the tables which are available on a given night.
Thanks.
EDIT::
This is what i have tried. (Some of it is pseudo as i am not quite sure how to do it)
SELECT tables.table_id
FROM tables
LEFT JOIN table_allocation
ON tables.table_id = table_allocation.table_id
WHERE table_allocation.table_id is NULL;
This returns the well empty rows as it is checking for the none presence of the table. I am not quite sure how i would do the date bit test.
To find TABLE rows that have no TABLE_ALLOCATION rows on a given THEMED_NIGHT.TEME_NIGHT_DATE, you should be able to do something like this:
SELECT *
FROM TABLES
WHERE
TABLE_ID NOT IN (
SELECT TABLE_ALLOCATION.TABLE_ID
FROM
TABLE_ALLOCATION
JOIN RESERVATION
ON TABLE_ALLOCATION.RESERVATION_ID = RESERVATION.RESERVATION_ID
JOIN THEMED_NIGHT
ON RESERVATION.THEME_ID = THEMED_NIGHT.THEME_ID
WHERE
THEME_NIGHT_NAME = :the_date
)
In plain English:
Join TABLE_ALLOCATION, RESERVATION and THEMED_NIGHT and accept only those that are on the given date (:the_date).
Discard the TABLE rows that are related to the tuples above (NOT IN).
Those TABLE rows that remain are free for the night.
Try:
SELECT tables.table_id
FROM tables t
WHERE NOT EXISTS
(SELECT NULL
FROM table_allocation a
JOIN reservation r
ON a.reservation_id = r.reservation_id and
r.`TIME` between :Date and :Date+1
WHERE t.table_id = a.table_id)
Note: will only return tables that are not booked at any point on the day in question.
I'm implementing an audit log on a database, so everything has a CreatedAt and a RemovedAt column. Now I want to be able to list all revisions of an object graph but the best way I can think of for this is to use unions. I need to get every unique CreatedAt and RemovedAt id.
If I'm getting a list of countries with provinces the union looks like this:
SELECT c.CreatedAt AS RevisionId from Countries as c where localId=#Country
UNION
SELECT p.CreatedAt AS RevisionId from Provinces as p
INNER JOIN Countries as c ON p.CountryId=c.LocalId AND c.LocalId = #Country
UNION
SELECT c.RemovedAt AS RevisionId from Countries as c where localId=#Country
UNION
SELECT p.RemovedAt AS RevisionId from Provinces as p
INNER JOIN Countries as c ON p.CountryId=c.LocalId AND c.LocalId = #Country
For more complicated queries this could get quite complicated and possibly perform very poorly so I wanted to see if anyone could think of a better approach. This is in MSSQL Server.
I need them all in a single list because this is being used in a from clause and the real data comes from joining on this.
You have most likely already implemented your solution, but to address a few issues; I would suggest considering Aleris's solution, or some derivative thereof.
In your tables, you have a "removed at" field -- well, if that field were active (populated), technically the data shouldn't be there -- or perhaps your implementation has it flagged for deletion, which will break the logging once it is removed.
What happens when you have multiple updates during a reporting period -- the previous log entries would be overwritten.
Having a separate log allows for archival of the log information and allows you to set a different log analysis cycle from your update/edit cycles.
Add whatever "linking" fields required to enable you to get back to your original source data OR make the descriptions sufficiently verbose.
The fields contained in your log are up to you but Aleris's solution is direct. I may create an action table and change the field type from varchar to int, as a link into the action table -- forcing the developers to some standardized actions.
Hope it helps.
An alternative would be to create an audit log that might look like this:
AuditLog table
EntityName varchar(2000),
Action varchar(255),
EntityId int,
OccuranceDate datetime
where EntityName is the name of the table (eg: Contries, Provinces), the Action is the audit action (eg: Created, Removed etc) and the EntityId is the primary key of the modified row in the original table.
The table would need to be kept synchronized on each action performed to the tables. There are a couple of ways to do this:
1) Make triggers on each table that will add rows to AuditTable
2) From your application add rows in AuditTable each time a change is made to the repectivetables
Using this solution is very simple to get a list of logs in audit.
If you need to get columns from original table is also possible using joins like this:
select *
from
Contries C
join AuditLog L on C.Id = L.EntityId and EntityName = 'Contries'
You could probably do it with a cross join and coalesce, but the union is probably still better from a performance standpoint. You can try testing each though.
SELECT
COALESCE(C.CreatedAt, P.CreatedAt)
FROM
dbo.Countries C
FULL OUTER JOIN dbo.Provinces P ON
1 = 0
WHERE
C.LocalID = #Country OR
P.LocalID = #Country