Update Column based on SELECT with Parameter coming from UPDATE - sql-server-2008

I want to do something like this.
UPDATE tbl_states AS ts
SET tbl_states.country_id = (SELECT tbl_countries.country_id
FROM tbl_states ts1
JOIN tbl_countries
ON tbl_countries.country_id_id =
ts1.country_id
WHERE ts1.country_id_id = ts.country_id_id)
I want to update old country_id which came from different database to new country_id based on new primary keys inserted on the new database. To give you an idea here is the schema.
CREATE TABLE [dbo].[tbl_countries](
[country_id] [int] IDENTITY(1,1) NOT NULL,
[country_id_id] [int] NULL,
[country_name] [varchar](50) NULL)
country_id_id is the old country_id referenced on the next table I will show you tbl_states
CREATE TABLE [dbo].[tbl_states](
[state_id] [int] IDENTITY(1,1) NOT NULL,
[state_name] [varchar](50) NULL,
[country_id] [int] NULL,
[state_abbr] [char](3) NOT NULL)
I want to update country_id column of this table tbl_states to primary column of the table above using the following select statement to get the primary key.
SELECT tbl_countries.country_id
FROM tbl_states_old
JOIN tbl_countries
ON tbl_countries.country_id_id = tbl_states_old.country_id
Sorry for the title, I don't know what this is called. Could you help me with this?

UPDATE s
SET country_id = c.country_id
FROM tbl_states s
INNER JOIN tbl_countries c
ON s.country_id = c.country_id_id

Related

Select the oldest from join

I'm making my own archive system. Here is how it looks so far. I have following SQL tables:
CREATE TABLE items (
id int NOT NULL AUTO_INCREMENT,
serial_number varchar(255) NOT NULL,
catalog_number varchar(255) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE entities (
id int NOT NULL AUTO_INCREMENT,
table_name varchar(255) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE entities_relations (
id int NOT NULL AUTO_INCREMENT,
table_name varchar(255) NOT NULL,
entity_id int NOT NULL,
row_id int NOT NULL,
PRIMARY KEY (id)
);
Each entity where table_name is "items" has at least one item matched via entities_relations. entities_relations shows how many relations are between one entity and items. After saving an item it saves a new Item which is a copy of the previous one and adds a relation. Copies (archive items) don't create a new entity, they create only relation. The oldest relation is the original item.
The following SQL syntax shows me items list. It's wrong because it shows me all items, even if they are archived. I would like to display only the original ones. How can I change it to be able to display only original ones and ignore archives?
SELECT
items.*,
FROM
items
LEFT JOIN entities_relations ON
entities_relations.row_id = items.id
LEFT JOIN entities ON
entities.id = entities_relations.entity_id
WHERE
entities.name = 'items'
ORDER BY
entities.id DESC,
entities_relations.entity_id DESC
LIMIT 0, 50

Find Unique Value based on criteria

Hello… I am trying to figure out how to look under ModelName column, which could contain duplicate values and see if ReleaseType column for that same model contains “Final Release.” If yes, do nothing, if not Return Unique ModelName (perhaps based on the latest Date). Fields in Green are the one I am trying to show and the one in red should not be visible:
Is this something that could be done in SQL Server 2019?
Here are my tables:
CREATE TABLE [dbo].[Model](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ModelName] [nvarchar](50) NOT NULL,
[FormFactorID] [int] NOT NULL,
[Revision] [nvarchar](4) NOT NULL,
[SVID] [nvarchar](4) NOT NULL,
[SSID] [nvarchar](4) NULL,
[Picture] [varbinary](max) NULL,
[NVME] [nvarchar](4) NULL,
[ReleaseStatusID] [int] NULL,
CONSTRAINT [PK__Model__3214EC27B0574C2B] PRIMARY KEY CLUSTERED
CREATE TABLE [dbo].[ReleaseType](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ReleaseType] [nvarchar](15) NULL,
CONSTRAINT [PK__ReleaseT__3214EC27CD0730DB] PRIMARY KEY CLUSTERED
CREATE TABLE [dbo].[ProductRelease](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ReleaseTypeID] [int] NULL,
[ModelID] [int] NULL,
[Date] [date] NULL,
[ECO] [nvarchar](10) NULL,
[Notes] [nvarchar](800) NULL,
CONSTRAINT [PK__ProductR__3214EC27CE911F54] PRIMARY KEY CLUSTERED
ID from ReleaseType table joined with ReleaseTypeID from ProductRelease table
ID from Model table joined with ModelID from ProductRelease table
Here is my Query so far:
SELECT
dbo.Model.ModelName,
dbo.ReleaseType.ReleaseType,
dbo.ProductRelease.ECO,
dbo.ProductRelease.Date
FROM
dbo.Model
INNER JOIN dbo.ProductRelease ON dbo.Model.ID = dbo.ProductRelease.ModelID
INNER JOIN dbo.ReleaseType ON dbo.ProductRelease.ReleaseTypeID = dbo.ReleaseType.ID
ORDER BY
dbo.Model.ModelName,
dbo.ProductRelease.Date
Yes, it doable for instance with windowed fucntions:
WITH cte AS (
SELECT m.ModelName,
rt.ReleaseType,
pr.ECO,
pr.Date,
cnt = COUNT(CASE WHEN rt.ReleaseType='Final Release' THEN 1 END)
OVER(PARTITION BY m.ModelName),
rn = ROW_NUMBER() OVER(PARTITION BY m.ModelName ORDER BY pr.Date DESC)
FROM dbo.Model m
JOIN dbo.ProductRelease pr
ON m.ID = pr.ModelID
JOIN dbo.ReleaseType rt
ON pr.ReleaseTypeID = rt.ID
)
SELECT ModelName, ReleaseType, ECO, Date
FROM cte
WHERE cnt = 0 -- exclude groups with 'Final Release'
AND rn = 1 -- get only newest occurence per ModelName
ORDER BY ModelName;

Is there anyway to insert only unique entries into a pivot table in MYSQL?

I have tried to use INSERT IGNORE but still I can see that when I runs the query again. It still inserts the records. I don't want to insert duplicate records in there.
Can anyone help me out?
INSERT INTO enquiry_location_status
(enquiry_id,
location_id,
enquiry_status)
SELECT we.id AS enquiry_id,
wl.location_id AS location_id,
we.status AS enquiry_status
FROM enquiry we
LEFT JOIN wishlist w
ON w.enquiry_id = we.id
LEFT JOIN wishlist_location wl
ON wl.wishlist_id = w.id
WHERE wl.wishlist_id IS NOT NULL;
My table definition:
CREATE TABLE `enquiry_location_status` (
`id` bigint(20) NOT NULL,
`enquiry_id` int(10) NOT NULL,
`location_id` int(11) NOT NULL,
`enquiry_status` varchar(30) NOT NULL
);
ALTER TABLE `enquiry_location_status`
ADD PRIMARY KEY (`id`);
ALTER TABLE `enquiry_location_status`
MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT;
Here is a screenshot how my pivot table data looks like:
I have tried this, it seems to be working but it's very slow. It's taking 80 seconds for 40 K+ records just.
INSERT INTO enquiry_location_status
(enquiry_id,
location_id,
enquiry_status)
SELECT we.id AS enquiry_id,
wl.location_id AS location_id,
we.status AS enquiry_status
FROM enquiry we
LEFT JOIN wishlist w
ON w.enquiry_id = we.id
LEFT JOIN wishlist_location wl
ON wl.wishlist_id = w.id
WHERE wl.wishlist_id IS NOT NULL
AND NOT EXISTS (SELECT els.enquiry_id,
els.location_id,
els.enquiry_status
FROM enquiry_location_status els
WHERE els.enquiry_id = we.id
AND els.location_id = wl.location_id
AND els.enquiry_status = we.status)
Thanks

MySQL update a table and select from the same table in a subquery

I have table of link
CREATE TABLE `linktable` (
`id ` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`idParent` BIGINT(20) UNSIGNED NOT NULL,
`Role` ENUM('Contacts','Expert','...') NULL DEFAULT NULL,
`idChild` BIGINT(20) UNSIGNED NOT NULL,
PRIMARY KEY (`idt`),
UNIQUE INDEX `UK_Parent_Child_Role` (`idParent`, `idChild`, `Role`)
)
I want to update this table and don’t break the unique key.
With other database I make something like this :
Update linktable lt1 Set lt1.Parent = :ziNew Where lt1.idParent = :ziOld
and not exists (select * from linktable lt2 where lt2.idParent = :ziNew and lt1.role = lt2.role and lt1.idChild = lt2.idChild);
How to make this with MySQL ?
Using your same syntax for variables, you would do this with a join:
Update linktable lt1 left outer join
(select *
from linktable lt2
where lt2.idParent = :ziNew
) lt2
on lt1.role = lt2.role and lt1.idChild = lt2.idChild
Set lt1.Parent = :ziNew
Where lt1.Parent =:ziOld and lt2.idParent is null;
The problem in MySQL is that the subquery is one the same table as the updated table. If it were a different table, then the original form with not exists would still work.

select multiple rows from tow tables mysql

I'm trying to select mltiple rows from tow table :
first table is donor
CREATE TABLE donor(
donor_number INT NOT NULL AUTO_INCREMENT,
d_name VARCHAR(30) NOT NULL,
mobile_number INT NOT NULL,
blood_group VARCHAR(20) NULL,
dob DATE NOT NULL,
gender ENUM('male','female') NOT NULL,
govid INT(10) NOT NULL,
PRIMARY KEY (donor_number )
);
second table is blood_donation
CREATE TABLE blood_donation(
donor_number INT NOT NULL,
date_of_donate DATE NOT NULL,
blood_group VARCHAR(20) NULL,
serial_number INT(10) NOT NULL,
blood_component ENUM('wb','prcb') NOT NULL,
PRIMARY KEY (donor_number , date_of_donate ),
FOREIGN KEY (donor_number) REFERENCES donor(donor_number)
);
with this select statement:
SELECT
serial_number,
blood_group
FROM blood_donation
WHERE date_of_donate = '2012-07-18'
UNION ALL
SELECT
blood_group
FROM donor
WHERE donor.donor_number=blood_donation.donor_number;
but, I get error
SQL state 42S22: Unknown column 'blood_donation.donor_number' in 'where clause'
any idea????
Actually you should not be using UNION but JOIN :)
you query will look like this
SELECT
blood_donation.serial_number,
donor.blood_group
FROM
blood_donation ,
donor
WHERE donor.donor_number = blood_donation.donor_number AND date_of_donate = '2012-07-18' ;
A UNION is used to combine more than one result set into a single result set - and each result set must have the same set of columns.
What you need is a JOIN, which is how you link multiple tables together on foreign keys etc and would be something like this:
SELECT
serial_number,
blood_group
FROM blood_donation
INNER JOIN donor ON donor.donor_number=blood_donation.donor_number
WHERE date_of_donate = '2012-07-18'
SELECT
dd.serial_number,
dd.blood_group
FROM blood_donation dd
inner join
donor d
on d.donor_number=dd.donor_number
WHERE dd.date_of_donate = '2012-07-18';
UNION is not what exactly you need, Read some more about JOINS. Also please change the selection alias of columns as per the need. And you can use Left Join instead of Inner Join if you don't want a mandatory join condition on tables.