I am going to do my best to clearly describe what I am trying to do.
I am using a DBISAM SQL database.
We sell t-shirts, and lots of different kinds. I am trying to update our product database with values from other products in the database. here is an sample:
Products Table
SKU Product LongDesc
01-S 01 Great Looking T-Shirt
01-M 01
01-L 01
02-S 01
02-M 01 Amazing Ladies T
02-L 01
03-32 03 Long t
03-34 03
03-36 03
I would like to write an update script that will update the LongDesc field on all SKU's that don't have a LongDesc but I would like that to get there LongDesc from other SKU's with the same Product
IN THE END I WOULD LIKE THE TABLE TO LOOK LIKE THIS:
SKU Product LongDesc
01-S 01 Great Looking T-Shirt
01-M 01 Great Looking T-Shirt
01-L 01 Great Looking T-Shirt
02-S 01 Amazing Ladies T
02-M 01 Amazing Ladies T
02-L 01 Amazing Ladies T
03-32 03 Long t
03-34 03 Long t
03-36 03 Long t
Thanks in advance for your help!
Try this:
UPDATE p
SET p.longdesc = pp.longdesc
FROM products p
INNER JOIN
(
SELECT a.sku, MAX(a.longdesc) AS longdesc
FROM
(
SELECT LEFT(sku FOR (POS('-', sku) - 1)) AS sku, longdesc
FROM products
) a
GROUP BY a.sku
) pp ON LEFT(p.sku FOR (POS('-', p.sku) - 1)) = pp.sku
Related
I have a table in Access database, I would like to transform AT_cd column into rows using SQL query in MS Access (as below result table) but I am unable to transform it correctly. I tried to transform using the below query but it is transforming the AT_cd into 200+ columns. I am not sure how to correct my query. Below is the sample table and desired result table provided. Any help much appreciated.
Table:
ID AT_cd
01 BB01A
01 IZ76N
02 AC21B
02 AX30A
02 ZA98A
03 AC21N
03 ZA76M
03 RT67T
04 QS70P
04 TR67A
04 GB45L
04 AC78M
Desired result:
ID AT_cd1 AT_cd2 AT_cd3 AT_cd4
01 BB01A IZ76N
02 AC21B AX30A ZA98A
03 AC21N ZA76M RT67T
04 QS70P TR67A GB45L AC78M
Code:
TRANSFORM FIRST(AT_cd)
SELECT [ID]
FROM Table1
GROUP BY [ID]
PIVOT AT_cd
With DCount you can get close using this query that also will sort the column values:
TRANSFORM
First(QueryQ.AT_cd)
SELECT
QueryQ.ID
FROM
(SELECT
ID,
AT_cd,
"AT_cd" & CStr(DCount("*", "TableQ", "[ID] = '" & ID & "' And [AT_cd] <= '" & AT_cd & "'")) AS Sequence
FROM
TableQ) As QueryQ
GROUP BY
QueryQ.ID
PIVOT
QueryQ.Sequence;
Edit: From Duane Hookom I was suggested this alternative method using SQL only, thus perhaps faster:
TRANSFORM
First(QueryQ.AT_cd)
SELECT
QueryQ.ID
FROM
(SELECT TableQ.ID, TableQ.AT_cd, Count(TableQ.AT_cd) AS Sequence
FROM TableQ
INNER JOIN TableQ AS TableQ_1 ON TableQ.ID = TableQ_1.ID
WHERE (((TableQ.AT_cd)>=[TableQ_1].[AT_cd]))
GROUP BY TableQ.ID, TableQ.AT_cd) As QueryQ
GROUP BY
QueryQ.ID
PIVOT
"AT_cd" & QueryQ.Sequence;
I am afraid what you want is not possible. You are trying to get results based on the order of the records in the record-list, and this cannot be done. You need to create a specific field that states the order, and then you can do it. The field that states the order would be something like:
ID AT_cd Order
01 BB01A AT_cd1
01 IZ76N AT_cd2
02 AC21B AT_cd1
02 AX30A AT_cd2
02 ZA98A AT_cd3
03 AC21N AT_cd1
03 ZA76M AT_cd2
03 RT67T AT_cd3
04 QS70P AT_cd1
04 TR67A AT_cd2
04 GB45L AT_cd3
04 AC78M AT_cd4
Once you do this, the following TRANSFORM produces your desired result:
TRANSFORM First(AT_cd)
SELECT ID
FROM Table_name
GROUP BY ID
ORDER BY ID
PIVOT Order
More information at LightningGuide.net.
I need to update multiple values in a single column based on a "legend" (for lack of a better word).
Let's say this is my current table (CUSTOMERS)
Cust_Name
Bank
William
01
Harry
02
John
05
Jack
01
Matthew
03
And this is the "legend"
This legend does not exist in the database it is just used to explain my example. It is just a way to present the corresponding values
Bank Number
Bank
01
Chase
02
BankOfAmerica
03
JPMorgan
04
WellsFargo
05
Citigroup
I want to update the Customers table to show the name of the Bank instead of the Bank Number.
When I first tried to do this it looked like this :
update CUSTOMERS
set BANK = 'Chase'
where BANK = '01' ;
update CUSTOMERS
set BANK = 'BankOfAmerica'
where BANK = '02' ;
...
Which had to be executed line by line.
Does anyone know how I can execute this in one go?
Thank you in advance.
use
UPDATE CUSTOMERS
SET BANK = CASE
WHEN BANK = '01' THEN 'Chase'
WHEN BANK = '02' THEN 'BankOfAmerica'
WHEN BANK = '03' THEN 'JPMorgan'
WHEN BANK = '04' THEN 'WellsFargo'
WHEN BANK = '05' THEN 'Citigroup'
END
demo in db<>fiddle
In Postgres, you would express this as:
update customers c
set bank = l.bank
from legend l
where c.bank = l.bank_no;
However, I do not see why you would want to update the actual name. Why not just use a join when you query the table?
EDIT:
Based on your comment, you should create the legend table. In any case, you can create a version just for the query:
update customers c
set bank = l.bank
from (values ('01', 'Chase'),
('02', 'BankOfAmerica'),
('03', 'JPMorgan'),
('04', 'WellsFargo'),
('05', 'Citigroup')
) v(bank_no, bank);
where c.bank = l.bank_no;
you can update from a VALUES clause:
update customers c
set bank = v.bank_name
from (
values
('01', 'Chase'),
('02', 'BankOfAmerica'),
('03', 'JPMorgan'),
('04', 'WellsFargo'),
('05', 'Citigroup')
) as v(bank_number, bank_name)
where v.bank_number = c.bank;
Suppose I have a table, cars, which looks like this:
id | model | car_color
----+--------+--------
01 | Camry | blue
02 | Elantra| red
03 | Sienna | blue
04 | Camry | fuschia
05 | LX450 | pink
06 | Tundra | lime
Also suppose I have this other table, a non-exhaustive of colors, colors:
colors
-------
blue
red
fuschia
In Postgres (or perhaps in any SQL variant), how can I count how many entries in cars.car_color match any of the entries in colors.colors?
The answer here would be 4, as 'pink' and 'lime' don't appear in the colors table, but I can't get Postgres to spit this back for me. (In what I'm actually working on, the first table has dozens of millions of rows, and the second table I'm checking against has about 100k.) I'm trying things like this, to no avail:
select count(*) from cars
where "car_color" IN (colors.colors)
Here's the error:
[42P01] ERROR: missing FROM-clause entry for table "colors"
My intuition is that this is something about my WHERE statement, but I can't figure out what. Nor can I seem to phrase this in such a way as to get good search results in Google or SX search -- I know I'm not the first (or the 257th) to ask this.
Close. You need a subquery:
select count(*)
from cars c
where c.car_color IN (select co.color from colors co);
Postgres as a good optimizer, but sometimes exists works better:
select count(*)
from cars c
where exists (select 1 from colors co where co.color = c.car_color);
Here is a db<>fiddle.
Wow that title is a doozy.
Here's the situation...
I have three tables.
APPLICATIONS: The first table is a catalog of applications, these applications contain an application ID, the Application Name, and other fields unimportant to this question.
INVENTORY: The second table is a list of deployments of these applications. The deployments contain the application name, application Id, the inventory ID, the division, the facility, and other fields unimportant to this question.
FRMP: The third table is a table created whenever an inventory record is created; this table tells us whether or not the inventory records hold confidential information. It contains an application ID, an Inventory ID, an FRMP ID, and a column that determines if the inventory record associated with it contains sensitive data.
The relations:
An application can belong to many inventory records, but an inventory record can only have one application. An FRMP record must have only one Inventory record associated to it, but an inventory record can exist without an FRMP record.
Here's what I'm trying to do, and have been struggling to do for the past two days...
I need a list of every application (by name) where for every record in which it is deployed, not a single one of those deployments contains sensitive data.
For example, if record 250 in Inventory has application name 74 and FRMP.HoldsSensitive = "No", but record 379 in Inventory has application name 74 and FRMP.HoldsSensitive = "Yes", I don't want to see application 74.
This is NOT as easy as it looks.
EDIT
Here is some example data and the preferred output.
AppID AppName Vendor
01 FooIt Goodstuff Inc
02 BarIt Greatstuff Co
03 SaltIt Sweet Inc
04 SugarIt Sweet Inc
InvID AppName Division Facility
01 FooIt Corporate Nearville
02 SaltIt Corporate Farville
03 SaltIt USA Sin City
04 SugarIt USA Sin City
05 BarIt USA Vice City
06 BarIt USA Sin City
07 FooIt USA Sin City
08 SaltIt USA Vice City
FRMPID INVID APPID HoldsSS
01 01 01 Yes
02 02 03 Yes
03 03 03 No
04 05 02 No
05 06 02 No
06 07 01 No
07 08 03 Yes
The query should only return BarIt. It should not return SugarIt because SugarIt doesn't exist within the Inventory table.
If you just wanna retrieve the application names, how 'bout
SELECT ApplicationName
FROM APPLICATIONS
WHERE NOT EXISTS
(
SELECT *
FROM FRMP
WHERE FRMP.ApplicationID = APPLICATIONS.Application_ID
AND FRMP.HoldsSensitive = 'Yes'
)
AND EXISTS
(
SELECT *
FROM INVENTORY
WHERE INVENTORY.Application_ID = APPLICATIONS.Applications_ID
)
I have 1 table "Products" that looks like this:
ID Product Shop Color
01 Car A Black
02 Car B Black
03 Bike C Red
04 Plane A Silver
05 Car C Black
06 Bike A Red
In this example, a Product always has the same color, independent from the Shop where it is sold.
I want to make a query, that returns a distinct set of products, with the Color property. I also will need to have an ID, it could be any ID, that allows me to do a follow up query.
The result of the query should be:
ID Product Color
01 Car Black
03 Bike Red
04 Plane Silver
I tried:
SELECT DISTINCT
Product, Color
FROM
Products
But that obviously doesn't return the ID as well
I guess I need to join something, but my knowledge of SQL is too poor. I hope this is something simple.
This would be one way of getting the result you want:
SELECT min(ID), Product, Color FROM table GROUP BY Product, Color;
How About
SELECT
Product, Color, Min(ID)
FROM
TABLE
GROUP BY
Product, Colour
That'll return unique Product/Color Combinations and the first (lowest) ID found.
You need to use the GROUP BY clause.
The same but obtaining the maximun ID:
SELECT MAX(ID) AS ID, Product, Color
FROM Products
GROUP BY Product, Color
ORDER BY ID