UPDATE nested array field BigQuery - google-bigquery

I have two table Order and Person, where i am trying to update name in Order table from Person table by matching id.
Could anyone help on to frame the update query.
Tables
Order
Person

UPDATE `projectID.dataset.order` o
SET o.product.items.customer.name =
(SELECT name FROM `projectID.dataset.person` p
WHERE o.product.items.customer.id = p.id )
WHERE TRUE;

Related

Sql Update Count Details after grouping

I have multiple tables in my SQL Server database.
I have one table say Table A which has fields like dispatch,filename,etc.
The second table say Table B has filedetails like filename, dispatchcount, totalcount etc.
There are many other fields in both tables but not relevant to this question.
Requirement is :
I want to update Table B dispatch count after grouping Table A customers where dispatch is Y.
As I want to update the Table B using the result of grouping should I create a temp Table of the result or please guide:
Query:
update Collation_Data set Dqty=T.count1
from (select [collation_code],count(1) as 'count1'
FROM [Tatkal].[dbo].[Tatkal_Merge] T
where Dscan='Y'
group by [collation_code]) where srno=T.[collation_code]
In SQL Server, you can use a join with an aggregation query. I want to point out that you should use left join if you want to update all rows in collation_data, even those with no matches:
update c
set c.Dqty = cm.cnt
from Collation_Data c left join
(select collation_code, count(*) as cnt
from [Tatkal].[dbo].[Tatkal_Merge] m
where Dscan = 'Y'
group by collation_code
) cm
on c.srno = cm.collation_code;
You can also do this with a correlated subquery:
update Collation_Data c
set Dqty = (select count(*)
from [Tatkal].[dbo].[Tatkal_Merge] m
where m.Dscan = 'Y' and m.collation_code = c.collation_code
);
This can be quite efficient with an index on Tatkal_Merge(collation_code, Dscan).
I want to update the Table B using the result of grouping should I create a temp Table of the result or please guide
update c
set c.Dqty=T.count1
from Collation_Data c
join
(select [collation_code],count(1) as 'count1'
FROM [Tatkal].[dbo].[Tatkal_Merge]
where Dscan='Y'
group by [collation_code])t
on c.srno=T.[collation_code]

Iterate through one table to update another table on sql

I'm using Postgresql and it is costly to use count. What I'm trying to do is counting one table ids in another one and update count number.
Let's say first table is categories
id
name
num_count
Other table is Restaurants
id
name
category_id
I want to update categories.num_count based on the count value of Restaurants.category_id.
I can do this with
Update Categories set Categories.num_count = (select count(*) from Restaurants where Restaurants.category_id = Categories.id)
yet it tooks too much time. I tried to do something like iterate Restaurants 1 time and update Categories.num_count ++ but i couldn't do it right because it makes every categories num_count 1. It stops working after 1 execution.
Is there a better way to do this with sql?
update categories c
set num_count = r.num_count
from (
select category_id, count(*) as num_count
from restaurants
group by category_id
) r
where c.id = r.category_id
How about:
with countPerCategory (categoryId, numCount) as
{
select category_id, count(*) from Restaurants
group by category_id
}
update Categories set num_count = countPerCategory.numCount
from countPerCategory
where Categories.id = countPerCategory.categoryId;
PS: I find it an unnecessary thing to do. You need to update the num_count whenever a Restaurant is added or deleted.

Re-numbering sub-sets of a table in SQL

I have a table which contains columns for: ComponentID, PartID, Position, Country and City. The primary key consists of ComponentID, PartID, Country and City.
I am using MS SQL Azure.
Potentially a "part" may be deleted. If this happens, I need to be able to reset all of the positions for components and parts, BUT partitioned by Country and city.
I have written the code below, but it throws a primary key error. Can anyone help?
-- Update the positions
;WITH CTE AS
(
SELECT Comp.Position,
RowNum = row_number() OVER (partition by Comp.Country, Comp.City order by Comp.Position ASC)
FROM Comp
WHERE Comp.CompID = #selectedComponent
)
UPDATE CTE
SET Position = RowNum
Your CTE is generating the new row positions for your data so you then need to Join that to your existing table to update the position values.
To do that, you will need to include all the primary key columns in the CTE, and then do an update over a join:
UPDATE dbo.Comp
SET Position = CTE.RowNum
FROM CTE
INNER JOIN DBO.Comp ON CTE.ComponentId = dbo.Comp.ComponentId
AND CTE.City = dbo.Comp.City AND CTE.Country = dbo.Comp.Country AND CTE.PartID = dbo.Comp.PartID

constructing complex sql statement

I need to select and update a table looking up values from other tables. The idea is to select some details from order, but get the names of the foreign key values using the id
For the select I tried:
SELECT [Order].order_date,
[Order].total_price,
[Order].order_details,
vehicle.reg_no,
Staff.name,
stock.name
FROM
Order,
vehicle,
staff,
stock
WHERE
order.id = #order_id
AND vehicle.id = Order.vehicle_id
AND staff.id = Order.staff_id
AND stock.id = Order.product_id
for the update that i tried
UPDATE order
SET
total_price = #total_price,
order_detail = #order_detail,
product_id = (select is from stock where name = #product_name),
customer_id = (select id from customer where name = #customer_name),
vehicle_regno = (select reg_no from vehicle where name = #name)
WHERE (id = #id)
both does not return anything. i hope am clear enough to get some help, but if not pls i will provide more info.
thanks for helping
You might want to try converting you INNER JOINs to a LEFT JOIN for the SELECT statement.
SELECT [Order].order_date,
[Order].total_price,
[Order].order_details,
vehicle.reg_no,
Staff.name,
stock.name
FROM
[Order]
LEFT JOIN vehicle
ON vehicle.id = [Order].vehicle_id
LEFT JOIN staff
ON staff.id = [Order].staff_id
LEFT JOIN stock
ON stock.id = [Order].product_id
WHERE
[order].id = #order_id
The reasons why this would make a difference is if either a) you allow nulls in the fk fields or b) you don't have fk contraints which may point to a problem with your design.
Your update statement should update some rows provided that the value of #id exists in the ORDER table but as #Danny Varod already commented you won't get rows back only the number of rows affected
You are comparing stock.id with Order.product_id, could that be the problem?
Otherwise why it is not returning any rows we would need to know the content of the tables, perhaps you need a left join instead of inner join to some of them?

SQL query look for exact match using inner join

I have 2 tables in SQL Server 2005 db with structures represented as such:
CAR:
CarID bigint,
CarField bigint,
CarFieldValue varchar(50);
TEMP: CarField bigint, CarFieldValue varchar(50);
Now the TEMP table is actually a table variable containing data collected through a search facility. Based on the data contained in TEMP, I wish to filter out and get all DISTINCT CarID's from the CAR table exactly matching those rows in the TEMP table. A simple Inner Join works well, but I want to only get back the CarID's that match ALL the rows in TEMP exactly. Basically, each row in TEMP is supposed to be denote an AND filter, whereas, with the current inner join query, they are acting more like OR filters. The more rows in TEMP, the less rows I expect showing in my result-set for CAR. I hope Im making sense with this...if not please let me know and I'll try to clarify.
Any ideas on how I can make this work?
Thank u!
You use COUNT, GROUP BY and HAVING to find the cars that have exactly that many mathicng rows as you expect:
select CarID
from CAR c
join TEMP t on c.CarField = t.CarField and c.CarFieldValue = t.CarFieldValue
group by CarID
having COUNT(*) = <the number you expect>;
You can even make <the number you expect> be a scalar subquery like select COUNT(*) from TEMP.
SELECT *
FROM (
SELECT CarID,
COUNT(CarID) NumberMatches
FROM CAR c INNER JOIN
TEMP t ON c.CarField = t.CarField
AND c.CarFieldValue = t.CarFieldValue
GROUP BY CarID
) CarNums
WHERE NumberMatches = (SELECT COUNT(1) FROM TEMP)
Haven't tested this, but I don't think you need a count to do what you want. This query ought to be substantially faster because it avoids a potentially huge number of counts. This query finds all the cars which are missing a value and then filters them out.
select distinct carid from car where carid not in
(
select
carid
from
car c
left outer join temp t on
c.carfield = t.carfield
and c.carfieldvalue = t.carfieldvalue
where
t.carfield is null
)
Hrm...
;WITH FilteredCars
AS
(
SELECT C.CarId
FROM Car C
INNER JOIN Temp Criteria
ON C.CarField = Criteria.CarField
AND C.CarFieldValue = Critera.CarFieldValue
GROUP BY C.CarId
HAVING COUNT(*) = (SELECT COUNT(*) FROM Temp)
)
SELECT *
FROM FilteredCars F
INNER JOIN Car C ON F.CarId = C.CarId
The basic premise is that for ALL criteria to match an INNER JOIN against your temp table must produce as many records as there are within that table. The HAVING clause at the end of the FilteredCars query should widdle the results down to those that match all criteria.