Update rows using data within the same table SQL - sql

I have a table which looks like this
messageId | conversationId | campusA | campusB
1 1 campusA
2 1
3 1
4 1
5 2
6 2
7 2 campusB
As we can see multiple messages are linked to the same conversationId and we have campus information for some of the records. Using this information I want to update remaining empty rows that are linked to the same conversationId. For example, I can see campusA is linked to conversationId 1. Using this information, I want to update the remaining 3 rows that have the same conversationId as the first record.
I was having trouble figuring this out and was wondering what would be the most efficient way to go around this? Thank you in advance!

You can use the update and correlated sub query as follows:
Update your_table t
Set t.campusa = (select max(tt.campusa) from your_table tt
Where t.conversarion = tt.conversation)
Where t.campusa is null
And exists (select 1 from your_table tt
Where t.conversarion = tt.conversation and tt.campusa is not null)

Related

Access "Not In" query not working while only In is working correctly

I have below given query which is working fine but I want to use "Not In" operator instead of "In" but its giving no results:
SELECT DISTINCT OrderProdDetails.Priority
FROM OrderProdDetails
WHERE (((OrderProdDetails.Priority) In (SELECT DISTINCT OrderProdDetails.Priority
FROM OrderProdDetails WHERE (((OrderProdDetails.OrdID)=[Forms]![UpdateOrder]![OdrID])))));
Desired Query:
SELECT DISTINCT OrderProdDetails.Priority
FROM OrderProdDetails
WHERE (((OrderProdDetails.Priority) Not In (SELECT DISTINCT OrderProdDetails.Priority
FROM OrderProdDetails WHERE (((OrderProdDetails.OrdID)=[Forms]![UpdateOrder]![OdrID])))));
Basically it is referencing a control on parent form and based on that in a subform I want to populate the priority numbers i.e 1,2,3 and if for that record 1 is entered I want to get only 2 and 3 as drop-down option.
ReocordID OrdID Brand Name Priority
2 1 Org 1 2
3 2 Org 2 1
4 1 Org 1 1
6 1 Org 1 3
7 3 Org 3 1
8 4 Org 1 1
9 5 Org 2 1
10 5 Org 2 2
11 6 Org 1 1
12 6 Org 2 2
If there is any other better approach for the same please suggest.
Thanks in advance for your help.
In all likelihood, your problem is that Priority can take on NULL values. In that case, NOT IN doesn't work as expected (although it does work technically). The usual advice is to always use NOT EXISTS with subqueries rather than NOT IN.
But, in your case, I would suggest conditional aggregation instead:
SELECT opd.Priority
FROM OrderProdDetails as opd
GROUP BY opd.Priority
HAVING SUM(IIF(opd.OrdID = [Forms]![UpdateOrder]![OdrID], 1, 0)) = 0;
The HAVING clause counts the number of times the forms OdrId is in the orders. The = 0 means it is never there. Plus, you no longer need a select distinct.
Thanks for your prompt answers however I figured out what the problem was and the answer to problem is.
SELECT DISTINCT OrderProdDetails.Priority
FROM OrderProdDetails
WHERE (((OrderProdDetails.Priority) Not In (SELECT OrderProdDetails.Priority
FROM OrderProdDetails WHERE (((OrderProdDetails.OrdID)=[Forms]![UpdateOrder]![OdrID])
and ((OrderProdDetails.Priority) Is not null) ))));
I realized that the problem was happening only to those where there was a null value in priority so I puth the check of not null and it worked fine.
Thanks

Group by and sorting before a where clause?

I have a database that looks like this:
ID parent ticket category _record_status _log_user _log_timestamp _log_type
------------------------------------------------------------------------------------------------
1 1 1 1 active 1 2012-01-29 15:49:21 create
2 1 1 1 deleted 1 2012-01-29 15:52:14 destroy
3 3 1 2 active 1 2012-01-29 15:58:43 create
I want to be able to select all records that are not deleted for a specified ticket. However, this is difficult because of the revision system.
Is there a way to do this via SQL that is efficient, or would it be better to just do this in PHP, considering each ticket will only have a few records on average. I doubt any ticket would ever get more than 100 records in it's lifetime.
select *
from YourTable
where _record_status <> 'deleted'
and ticket = #yourTicketId
Is that what you're looking for??
Sql!
SELECT .....
FROM .....
WHERE _record_status!="deleted" AND ticket=X

Finding contiguous regions in a sorted MS Access query

I am a long time fan of Stack Overflow but I've come across a problem that I haven't found addressed yet and need some expert help.
I have a query that is sorted chronologically with a date-time compound key (unique, never deleted) and several pieces of data. What I want to know is if there is a way to find the start (or end) of a region where a value changes? I.E.
DateTime someVal1 someVal2 someVal3 target
1 3 4 A
1 2 4 A
1 3 4 A
1 2 4 B
1 2 5 B
1 2 5 A
and my query returns rows 1, 4 and 6. It finds the change in col 5 from A to B and then from B back to A? I have tried the find duplicates method and using min and max in the totals property however it gives me the first and last overall instead of the local max and min? Any similar problems?
I didn't see any purpose for the someVal1, someVal2, and someVal3 fields, so I left them out. I used an autonumber as the primary key instead of your date/time field; but this approach should also work with your date/time primary key. This is the data in my version of your table.
pkey_field target
1 A
2 A
3 A
4 B
5 B
6 A
I used a correlated subquery to find the previous pkey_field value for each row.
SELECT
m.pkey_field,
m.target,
(SELECT Max(pkey_field)
FROM YourTable
WHERE pkey_field < m.pkey_field)
AS prev_pkey_field
FROM YourTable AS m;
Then put that in a subquery which I joined to another copy of the base table.
SELECT
sub.pkey_field,
sub.target,
sub.prev_pkey_field,
prev.target AS prev_target
FROM
(SELECT
m.pkey_field,
m.target,
(SELECT Max(pkey_field)
FROM YourTable
WHERE pkey_field < m.pkey_field)
AS prev_pkey_field
FROM YourTable AS m) AS sub
LEFT JOIN YourTable AS prev
ON sub.prev_pkey_field = prev.pkey_field
WHERE
sub.prev_pkey_field Is Null
OR prev.target <> sub.target;
This is the output from that final query.
pkey_field target prev_pkey_field prev_target
1 A
4 B 3 A
6 A 5 B
Here is a first attempt,
SELECT t1.Row, t1.target
FROM t1 WHERE (((t1.target)<>NZ((SELECT TOP 1 t2.target FROM t1 AS t2 WHERE t2.DateTimeId<t1.DateTimeId ORDER BY t2.DateTimeId DESC),"X")));

Why does this query return "incorrect" results?

I have 3 tables:
'CouponType' table:
AutoID Code Name
1 CouT001 SunCoupon
2 CouT002 GdFriCoupon
3 CouT003 1for1Coupon
'CouponIssued' table:
AutoID CouponNo CouponType_AutoID
1 Co001 1
2 Co002 1
3 Co003 1
4 Co004 2
5 Co005 2
6 Co006 2
'CouponUsed' table:
AutoID Coupon_AutoID
1 2
2 3
3 5
I am trying to join 3 tables together using this query below but apparently I am not getting right values for CouponIssued column:
select CouponType.AutoID, Code, Name, Count(CouponIssued.CouponType_AutoID), count(CouponUsed.Coupon_AutoID)
from (CouponType left join CouponIssued
on (CouponType.AutoID = CouponIssued.CouponType_AutoID))
left join CouponUsed
on (couponUsed.Coupon_AutoID = CouponIssued.AutoID)
group by CouponType.AutoID, code, name
order by code
The expected result should be like:
**Auto ID Code Name Issued used**
1 CouT001 SunCoupon 3 2
2 CouT002 GdFriCoupon 3 1
3 CouT003 1for1Coupon 0 0
Thanks!
SELECT t.AutoID
,t.Code
,t.Name
,count(i.CouponType_AutoID) AS issued
,count(u.Coupon_AutoID) AS used
FROM CouponType t
LEFT JOIN CouponIssued i ON i.CouponType_AutoID = t.AutoID
LEFT JOIN CouponUsed u ON u.Coupon_AutoID = i.AutoID
GROUP BY 1,2,3;
You might consider using less confusing names for your table columns. I have made very good experiences with using the same name for the same data across tables (as far as sensible).
In your example, AutoID is used for three different columns, two of which appear a second time in another table under a different name. This would still make sense if Coupon_AutoID was named CouponIssued_AutoID instead.
change count(Coupon.CouponType_AutoID) to count(CouponIssued.CouponType_AutoID) and count(Coupon.Coupon_AutoID) to count(CouponUsed.Coupon_AutoID)

Update a variable number of rows each with different values in a single SQL command?

I have a table of ordered data like this
ID ORDER
12 1
13 2
14 3
15 4
...
200 189
201 190
...
I would like to be able to update a few or all of their "order"s.
How should I do that?
For example, I might switch the ordering between ID=12 and ID=13 so it'd go like
ID ORDER
12 2
13 1
14 3
15 4
...
This would just be a simple UPDATE TABLE SET ORDER=1 WHERE ID=13 SET ORDER=2 WHERE ID=12
But if I wanted to move ID=200 all the way to the top,..
ID ORDER
12 2
13 3
14 4
15 5
...
200 190
201 1
...
then everything would have to be updated..? How do I do that? Is there a better way? Decimals?
edit: I'm using MSSQL btw
edit:clarification of use: I have a table with a long list of URL links, and the order of those links matter. I want to be able to rearrange their order. I have a web page that retrieves that list from the db, displays the names as an unordered-list, and I can rearrange the items on that list. I'm stuck on how to get the newly ordered list's order updated into the database.
If you want to move an item up to the top, and update the order of all the other in a single statment, you can do the following:
UPDATE MyTable
SET Order = (CASE Order WHEN 190 THEN 1
ELSE Order + 1
END)
WHERE Order BETWEEN 1 AND 190
To move Id 200 to the top, you have to do this:
1) Take everything which is ordered before Id 200 and increase the order by 1
update MyTable
set Order = Order + 1
where Order < (select Order from MyTable where Id = 200)
2) Put Id 200 to the top of the list (Order = 1)
update MyTable
set Order = 1
where Id = 200
I think, What you are looking is
Select * from TableName order by ID Desc/Asc
You want to Order the rows, Ascending or Descending
I don't think the above question quite answers it. I believe the answer to your question is what you already suspect - to change order = 200 to order = 1, you will have to rescore every other value, or use a number format with decimals.
However, I strongly suspect that if you elaborated more on why you need to do it this way, we could chime in with some better recommended methods.