how to use tsql uniqueidentifier in a where not in clause - tsql

Trying to see if a uniqueidentifier exists in a where not in clause which contains a list of uniqueidentifiers... but this is not working.
select distinct cast(a.person_id as varchar(50))
from appointments a
where a.appt_date = '20140206'
and a.last_name like 'Smith123%'
and cast(a.person_id as varchar(50)) not in
(select cast(aa.person_id as varchar(50))
from appointments aa
where aa.appt_date < '20140206')
If I run the base query for Smith123% I get a uniqueidentifier.
Then if I run the not in select with an order by person_id I get many person_id values, but I do not see the uniqueidentifier I found earlier.... so I don't know why I don't get my one uniqueidentifier to display
Thanks in advance for any assistance
Dean-O

Related

Postgresql - how can I clone a set of records but maintain a mapping between the original ids and the new ids

I come from a SQL Server background and our team is migrating to Postgres (version 9.5).
We have a number of scripts that perform MERGE statements that essentially 'clone' rows in a table and insert them back into the same table with a new Id while maintaining a map between the cloned records and the records they were cloned from.
I'm having a hard time trying to replicate this behavior. I've tried a number of variations, but I still can't seem to find the right combination of temp tables and CTEs to get it right.
Here's an approximation of the latest version that doesn't work:
CREATE SCHEMA stackoverflow;
CREATE TABLE stackoverflow.clone_problem
(
id bigserial PRIMARY KEY NOT NULL,
some_id bigint NULL,
some_other_id bigint NULL,
modified_time timestamp NOT NULL DEFAULT now(),
modified_by varchar(128) NOT NULL DEFAULT current_user
);
INSERT INTO stackoverflow.clone_problem
(
id,
some_id,
some_other_id
)
VALUES (1,1,1)
,(2,2,2)
,(3,3,3);
;WITH sources
AS
(
SELECT
id as old_id,
some_id,
some_other_id
FROM stackoverflow.clone_problem
WHERE id = ANY('{1,3}')
),
inserts
AS
(
INSERT INTO stackoverflow.clone_problem
(
some_id,
some_other_id
)
SELECT
s.some_id,
s.some_other_id
FROM sources s
RETURNING id as new_id, s.id as old_id -- this doesn't work
)
SELECT * from inserts;
The final select statement is the output I'm trying to capture--either from a RETURNING statement of by other means-- so we know which records were cloned and what their new Ids are. But the code above throws this error: error: missing FROM-clause entry for table "s".
I don't understand because 's' is in the FROM clause so the error seems counterintuitive to me. I'm sure I'm missing something dumb, but I just can't seem to figure how to get that final piece of information.
Any help would be greatly appreciated.
I think your only chance is to generate the ID before you do the insert so that you have the mapping between old and new ID right away. This can be done by calling nextval() when retrieving the source rows, then providing that already generated ID during the INSERT
with sources as (
SELECT id as old_id,
nextval(pg_get_serial_sequence('stackoverflow.clone_problem', 'id')) as new_id,
some_id,
some_other_id
FROM clone_problem
WHERE id IN (1,3)
), inserts as (
INSERT INTO clone_problem (id, some_id, some_other_id)
SELECT s.new_id,
s.some_id,
s.some_other_id
FROM sources s
)
select old_id, new_id
from sources;
By using pg_get_serial_sequence you don't need know the name of the sequence directly.

How to use the same common table expression in two consecutive psql statements?

I'm trying to perform a pretty basic operation with a few steps:
SELECT data from table1
Use id column from my selected table to remove data from table2
Insert the selected table from step 1 into table2
I would imagine that this would work
begin;
with temp as (
select id
from table1
)
delete from table2
where id in (select id from temp);
insert into table2 (id)
select id from temp;
commit;
But I'm getting an error saying that temp is not defined during my insert step?
Only other post I found about this is this one but it didn't really answer my question.
Thoughts?
From Postgres documentation:
WITH provides a way to write auxiliary statements for use in a larger
query. These statements, which are often referred to as Common Table
Expressions or CTEs, can be thought of as defining temporary tables
that exist just for one query.
If you need a temp table for more than one query you can do instead:
begin;
create temp table temp_table as (
select id
from table1
);
delete from table2
where id in (select id from temp_table);
insert into table2 (id)
select id from temp_table;
commit;

How can I do something like this in PostgresQL?

Here is the snippet that I would like to happen. Is this possible?
INSERT INTO join_table_1(table_1_id,table_2_id)
SELECT id, (INSERT INTO table_2(id) VALUES (uuid_generate_v4()) RETURNING id)
FROM table_1
Looking at TRIGGER also but I can't find a way to return the id of the newly inserted row
It's not exactly clear to me what you are trying to achieve, but I think you are looking for a data modifying CTE
with new_t2 as (
INSERT INTO table_2(id)
VALUES (uuid_generate_v4())
RETURNING id
)
INSERT INTO join_table_1 (table_1_id, table_2_id)
SELECT id, (select id from new_t2)
FROM table_1

TSQL order by but first show these

I'm researching a dataset.
And I just wonder if there is a way to order like below in 1 query
Select * From MyTable where name ='international%' order by id
Select * From MyTable where name != 'international%' order by id
So first showing all international items, next by names who dont start with international.
My question is not about adding columns to make this work, or use multiple DB's, or a largerTSQL script to clone a DB into a new order.
I just wonder if anything after 'Where or order by' can be tricked to do this.
You can use expressions in the ORDER BY:
Select * From MyTable
order by
CASE
WHEN name like 'international%' THEN 0
ELSE 1
END,
id
(From your narrative, it also sounded like you wanted like, not =, so I changed that too)
Another way (slightly cleaner and a tiny bit faster)
-- Sample Data
DECLARE #mytable TABLE (id INT IDENTITY, [name] VARCHAR(100));
INSERT #mytable([name])
VALUES('international something' ),('ACME'),('international waffles'),('ABC Co.');
-- solution
SELECT t.*
FROM #mytable AS t
ORDER BY -PATINDEX('international%', t.[name]);
Note too that you can add a persisted computed column for -PATINDEX('international%', t.[name]) to speed things up.

PLSQL query for getting all records with MAX date

I'm working on a table which has more than 10 columns. One of the column name is ASAT which is of type DATE(Format is yyyy-mm-dd HH:MM:SS:mmm).
I'm looking for a sql query which returns all records of max date. Trying to use that query in java for JDBC call.
I tried this:
Select * from tablename where ASAT in (select MAX(ASAT) from tablename).
But it is not returning any records.
Any help is really appreciated.Thanks
How about:
SELECT MAX(Asat) FROM TableA;
SELECT MAX(Asat) FROM TableA GROUP BY Asat;
When you self join, I suggest aliasing each copy of the table. Personally I use the table letter with a number afterwards in case I need to track it for larger queries.
Select *
from tablename t1
where t1.ASAT = (
select MAX(t2.ASAT)
from tablename t2
)
I believe you are looking for something like this if I'm understanding you. First build a CTE containing the primary key and the MAX(ASAT). Then join to it, selecting where the primary key matches the primary key of the row with the MAX(ASAT). Note your "ID" may have to be more than one column.
with tbl_max_asat(id, max_asat) as (
select id, max(asat) max_asat
from tablename
group by id
)
select *
from tablename t
join tbl_max_asat tma
on t.id = tma.id;
This old post just popped up because it was edited today. Maybe my answer will still help someone. :-)