SQL query to override content of column when matched column - sql

Please who can help with this scenario?
I have two tables, both they have a common column ID, and Table 1 has a column Title. Normally I should update the content of this Title column for some ID, but since the table was already in use somewhere else, it wasn't a good idea to change data directly in Table 1.
That's why I created a new table table 2, which hold only the Title that must be changed associated with these ID that must be changed.
Now I am trying to get these updated titles from table 2, when there is a matching ID in table 1, otherwise show only the contents of table 1.
The result should be something like that but without using If statements.
__ID__ Title
| | | |
| | | |

You can use LEFT OUTER JOIN to this new table and COALESCE() function to say "If there is data in the new table, use it, otherwise use the data in the existing table" . Something like:
SELECT t1.id, COALESCE(t2.title, t1.title) as title
FROM t1
LEFT OUTER JOIN t2 ON t1.id = t2.id;

Related

SQL Developer - Updating/Inserting sum of column from different table based on distinct ID

Amateur SQL writer here having a problem with building out table based on values from an existing one.
The MASTER table logs a record with an ID every time a service is used. ID remains the same per user, but will repeat to track relevant information during that usage. Table holds about 2m records and 20k DISTINCT IDs.
*Example -
USER ID | Used_Amount
USER_1998 | 9GB,
USER_1999 | 4GB,
USER_1999 | 1GB,
USER_1999 |0.5 GB*
Would like for the new table is create column that SUMS the usage and organizes based on DISTINCT ID.
Goal -
ID . TOTAL USAGE
USER_1998 - 9GB
USER_1999 - 5.5GB
Code below is my attempt...
UPDATE ml_draft
SET true_usage = (
SELECT SUM(true_usage)
FROM table2 t2
INNER JOIN ml_draft ON
ml_draft.subscription_id = t2.subscription_id);
Let me know if there are any additional details to add. Errors vary
You want a correlated subquery. So, there is no need to use JOIN in the subquery:
UPDATE ml_draft d
SET true_usage = (SELECT SUM(t2.true_usage)
FROM table2 t2
WHERE d.subscription_id = t2.subscription_id
);
For performance, you want an index on table2(subscription_id, true_usage).

How to create a central parameter, like Report-Date?

I would like to create one location on sql server where I store the report-date and all queries and procedures should relate to this one value.
In that way I only have to change the report date on one location and it is valid for all related queries and procedures.
I started with a scalar function that retrieves a value from a table, but this slows down the queries enomoursly.
I tried an inline table valued function, but have no idea how to include this into a query.
I tried with a table that contains the report-date and used a cross join.
But it says:
The multi-part identifier could not be bound
Maybe some of you have an idea what to do here?
One possibility is to create a table, let's say TblReportDate with two columns: id and reportDate.
Then add one row with id 1 like following:
+----+------------+
| id | reportDate |
+----+------------+
| 1 | 04.04.2018 |
+----+------------+
Now join the table with a LEFT JOIN and use the >= operator to compare with the id-column of the main-table:
SELECT * FROM mainTable
LEFT JOIN TblReportDate ON mainTable.id >= TblReportDate.id

SQL join column of 1 table to row of another table

I have somewhat logical thing to do in SQL server, If my question is not valid or understandable pardon me , as I didn't knew how this question was supposed to be asked.
I have 2 tables which is to be converted into 3rd table.
1st table is a "Data" table having columns but their value is in codes whose TEXT which can be found in "Options" table.
State | Language | Gender
2 | 3 | 1
2nd table is "Options" Table which is a master table for converting code of "Data" table into text.
Question column is columns of "Data" table.
Option column is Text corresponding to code.
Code column is Value of "Data column"'.
Question | Option | Code
State | Orissa | 2
Language | English | 3
Suppose I want the Text of State column for code : 2 in "Data" table then I would look into "Options" table and get the Option columns value 'Orissa' corrrsponding to State and code 2.
Resultant table should contain only Texts converted from codes.
State | Language | Gender
Orissa | English | 1
1 thing to note is that Gender column didn't got converted text, because this column was 'NOT' contained in "Options table".
Result is to be created Dynamically as "Data" and "Options" table are created dynamically.
Any help would be appreciated.
Try joining your first table twice to the second table:
SELECT
COALESCE(t2.Option, 'NA') AS State,
COALESCE(t3.Option, 'NA') AS Language,
t1.Gender
FROM table1 t1
LEFT JOIN table2 t2
ON t1.State = t2.Code AND t2.Question = 'State'
LEFT JOIN table2 t3
ON t1.Language = t3.Code AND t3.Question = 'Language';

How to build virtual columns?

Sorry if this is a basic question. I'm fairly new to SQL, so I guess I'm just missing the name of the concept to search for.
Quick overview.
First table (items):
ID | name
-------------
1 | abc
2 | def
3 | ghi
4 | jkl
Second table (pairs):
ID | FirstMember | SecondMember Virtual column (pair name)
-------------------------------------
1 | 2 | 3 defghi
2 | 1 | 4 abcjkl
I'm trying to build the virtual column shown in the second table
It could be built at the time any entry is made in the second table, but if done that way, the data in that column would get wrong any time one of the items in the first table is renamed.
I also understand that I can build that column any time I need it (in either plain requests or stored procedures), but that would lead to code duplication, since the second table can be involved in multiple different requests.
So is there a way to define a "virtual" column, that could be accessed as a normal column, but whose content is built dynamically?
Thanks.
Edit: this is on MsSql 2008, but an engine-agnostic solution would be preferred.
Edit: the example above was oversimplified in multiple ways - the major one being that the virtual column content isn't a straight concatenation of both names, but something more complex, depending on the content of columns I didn't described. Still, you've provided multiple paths that seems promising - I'll be back. Thanks.
You need to join the items table twice:
select p.id,
p.firstMember,
p.secondMember,
i1.name||i2.name as pair_name
from pairs as p
join items as i1 on p.FirstMember = i1.id
join items as i2 on p.SecondMember = i2.id;
Then put this into a view and you have your "virtual column". You would simply query the view instead of the actual pairs table wherever you need the pair_name column.
Note that the above uses inner joins, if your "FirstMember" and "SecondMember" columns might be null, you probably want to use an outer join instead.
You can use a view, which creates a table-like object from a query result, such as the one with a_horse_with_no_name provided.
CREATE VIEW pair_names AS
SELECT p.id,
p.firstMember,
p.secondMember,
CONCAT(i1.name, i2.name) AS pair_name
FROM pairs AS p
JOIN items AS i1 ON p.FirstMember = i1.id
JOIN items AS i2 ON p.SecondMember = i2.id;
Then to query the results just do:
SELECT id, pair_name FROM pair_names;
You could create a view for your 'virtual column', if you wanted to, like so:
CREATE VIEW aView AS
SELECT
p.ID,
p.FirstMember,
p.SecondMember,
a.name + b.name as 'PairName'
FROM
pairs p
LEFT JOIN
items a
ON
p.FirstMember = a.ID
LEFT JOIN
items b
ON
p.SecondMember = b.ID
Edit:
Or, of course, you could just use a similar select statement every time.
When selecting from tables you can name the results of a column using AS.
SELECT st.ID, st.FirstMember, st.SecondMember, ft1.Name + ft2.Name AS PairName
FROM Second_Table st
JOIN First_Table ft1 ON st.FirstMember = ft1.ID
JOIN First_Table ft2 ON st.SecondMember = ft2.ID
Should give you something like what you are after.

Update a single table based on data from multiple tables SQL Server 2005,2008

I need to update table one using data from table two. Table one and two are not related by any common column(s). Table three is related to table two.
Ex : table one(reg_det table)
reg_det_id | reg_id | results
101 | 11 | 344
table two :(temp table)
venue | results
Anheim convention center | 355
Table three (regmaster-tbl)
reg_id| venue
11 | Anaheim convention center
I need to update results column in table one using data from table two. But table one and two are not related. Table two and three and table one and three are related as you can see above. Can anyone please suggest any ideas! I need the results value to be 355 in table one and this data is coming from table 2, but these two are unrelated, and they can be related using table three. Sorry if it is confusing!
Fairly straight forward:
UPDATE T1
SET result = t2.results
FROM [table one] T1
INNER JOIN [table three] t3
on t1.reg_id = t3.reg_id
INNER JOIN [table two] T2
on t2.venue = t3.venue
Almost a question instead of an answer. :)
Couldn't you use an implied inner join?
UPDATE rd
SET rd.results = tt.results
FROM reg_det rd, regmaster rm, temptable tt
WHERE rm.reg_id = rd.reg_id
AND rm.venue = tt.venue;
I find it easier to read, and this syntax works in a SELECT statement, with the same meaning as an explicit inner join.
Try this:
UPDATE rd
SET rd.results = t.results
FROM reg_det rd
JOIN regmaster rm ON rm.reg_id = rd.reg_id
JOIN temptable t ON t.venue = rm.venue
WHERE t.results = 355
I added a WHERE clause because otherwise it will update all reg_det records that have matches in regmaster and temptable.