Reputation: 64
Assume that I have a single table, with 3 records, [a], [b], [c]
.
I want to get back a, b, c
, until d
is created. D
can be a duplication of either a, b or c
, except the value in one column: x
will be different.
N.B: My DB is MySQL, my back-end in ColdFusion and when I say 'user edits' or 'user sees a list', I mean that the user sees a web page list of items to edit. If you think it would be better done programmatically as opposed to the database doing the work, I would appreciate the input.
So what I'd like is that:
a,b,c
.c
. c
is duplicated as d
, with a different value in column x
. a,b,d
. b
.b
is duplicated as e
, with a different value in column x
.a,e,d
.etc...
It seems like it should be a case of SELECT [fooRecord] UNLESS [barRecord exists]
in which case bring back [barRecord]
. I've looked around for similar answers, and some do use EXISTS
, but that only seems to return a true or false value, not the record I'm looking for. I believe it's a fancy sub query or INNER JOIN
that I need, but I'm at a loss to think up the exact syntax to do it.
This is my first time posting on SO so I apologise if I've done any part of it incorrectly or my question isn't clear, I will provide clarity or further info if asked for. Any help much appreciated.
Upvotes: 1
Views: 81
Reputation: 64
Arrived on the answer after some discussion with the team:
SELECT *
FROM
table1 t1
WHERE 1=1
AND (
x = <cfqueryparam value="#arguments.x#">
OR (
x is null
and
y not in
(
SELECT t2.et_code
FROM table2 t2
WHERE
t2.x = <cfqueryparam value="#arguments.x#">
)
)
)
I tried to format the answer so that it's easily readable. Thank you for the other answers.
Upvotes: 1
Reputation: 3488
I think, and I might be wrong so please correct me, that this is a NoSQL pattern. In that I, JaredE exist as a user in the users table, but my userid isn't the primary key of that table and thus anytime I or someone else edits my record it just inserts a new record rather than updates my existing record.
If you were to use this pattern, then you'd be doing something like
select distinct userid, a,b,c, lastmodified
from tbl
ORDER BY lastmodified desc
Upvotes: 1
Reputation: 7193
Your schema seems a bit convoluted - might be time to rethink that. Often the issue is an overwrought attempt to avoid additional tables or columns - but this might a case for additional meta data added to the schema to help pull this data. You might also consider simply selecting ALL the data (a,b,c,d,e) and simply using Q of a Q to tease out the row you want based on X.
Meanwhile, a CASE statement might get you there. This is total untested psuedo-code but it might give you an idea.
<Cfquery>
SELECT
CASE
WHEN x = *condition* THEN orig.col1
ELSE mod.col1
END CASE
AS col1,
CASE
WHEN x = *condition* THEN orig.col2
ELSE mod.col2
END CASE
AS col2
FROM tablename orig OUTER JOIN tablename mod
ON (orig.col1 = mod.col1
AND orig.col2 = mod.col2
AND orig.x <> orig.x)
</cfquery>
What I'm trying to do is join the 2 tables together and tease out one value vs the other based on whether or not it exists. I'm not sure I'm quite there with this query but you get the idea.
Another approach would be a UNION - something like this:
<Cfquery>
SELECT
col1, col2, col3
FROM tablename
WHERE *primarykey* NOT IN
(*select rows that DO have duplicates with modified x*)
UNION ALL
SELECT
col1, col2, col3
FROM tablename
WHERE *primarykey* IN
(*select rows that WITH the modified x*)
</cfquery>
This has the advantage of being a bit easier to understand. You can work with one query, then the other, then join them together to get what you want.
Good luck - seems daunting :)
Upvotes: 1