I'm trying to insert a new row in a table with count numbers from select statements from different tables. When I run the following, it creates the row but inserts 0 for the two fields with the select statements (instead of values 1047 and 8 that I get when I run the select statements individually) . I tried putting the select statements inside the insert statement as well but that was throwing errors. Any help on where I'm going wrong? Thanks in advance.
select count(*) from research.Neuro_Recruited_MG as letters_sent;
select count(*) from research.neuro_subject_log s where s.enrolled like 'PS' as pending_screening;
insert into neuro_stats (id, letters_sent, pending_screening)
values (3, 'letters_sent','pending_screening’)
You're running three separate statements. The first two (the SELECTs) execute, but starting the next one discards the one before it.
Try something like this instead:
insert into neuro_stats
(id, letters_sent, pending_screening)
values
(3,
(select count(*) from research.Neuro_Recruited_MG),
(select count(*) from research.neuro_subject_log s where s.enrolled like 'PS'));
try, assuming id is auto_increment.
insert neuro_stats(letters_sent, pending_screening)
select sum(count_letters_sent), sum(count_pending_Screening)
from (
select count(*) as count_letters_sent, 0 as count_pending_screening)
from research.neuro_recruited_MG
UNION
select 0 as count_letters_sent, count(*) as count_pending_screening
from reserach.neuro_subject_log as s
where s.enrolled like '%PS%'
) as xcount;
may be your like 'PS' needs the wildcard character % before and/or after your 'PS' in fact of a search like "beginning", "containing" or "ending" with 'PS'
Related
I am not so into database and maybe I am saying something trivial.
I am working on MySql and I have to implement a "complex" INSERT query.
I mean that I have to do something like this:
INSERT INTO MarketDetails_CommodityDetails
(market_detail_id, commodity_detail_id) VALUES
( XXX, YYY)
where XXX and YYY are not simple values but are the results of two SELECT queries both returning a single value (XXX is return by a SELECT query and YYY by another query).
I know that I can perform these queries, store the output in a variable and then call my insert query passing these parameters but I am asking if there is a way to automatically do it into my INSERT query.
Why do you want to use insert values ?
just perform an insert select
INSERT INTO MarketDetails_CommodityDetails(market_detail_id, commodity_detail_id)
select * from
(select --Complex select for XXX)
cross join
(select --Complex select for YYY)
You could also use values if you wanted to. Make sure you use 2 parenthesis instead of just 1 and make also sure to use limit statement even if your query always returns 1 row.
INSERT INTO some_final_table (column1, column2) VALUES (
(SELECT some_column_1 FROM some_middle_table_1 LIMIT 1),
(SELECT some_column_2 FROM some_middle_table_2 LIMIT 1)
)
Let assume Following simple table
Col1
======
one
two
Let assume Following simple query
Select count(*) from TABLE_A where Col1 in ('one','two','three','four')
In above query it will produce following result
2
Now I want to find out what are the values in IN- condition which is not available in table_A.
How to find out that values which are not available in table?
like below result
three
four
Above queries only example. In my real time query in have 1000 values in IN-Condition.
Working Database : DB2
This is the one of the work around to achieve your expectation.
Instead of hard-coding the values in IN condition, you can move those values in to a table. If it done simply using LEFT JOIN with NULL check you can get the not matching values.
SELECT MR.Col1
FROM MatchingRecords MR -- here MatchingRecords table contains the IN condition values
LEFT JOIN Table_A TA ON TA.Col1 = MR.Col1
WHERE TA.Col1 IS NULL;
Working DEMO
If the values are to be listed in the statement string rather than stored in a table, then perhaps a revision to the syntax being used for that list of values currently being composed [apparently, from some other input than a TABLE] for the IN predicate can be effected? The following revised syntax for a list of values could be used both for the original aggregate query [shown immediately below as the first of two queries], and for the query for which the how-to-code is being asked [the second of the two queries below]:
Select count(*)
from TABLE_A
where Col1 in ( values('one'),('two'),('three'),('four') )
; -- report from above query follows:
COUNT ( * )
2
[Bgn-Edit 05-Aug-2016: adding this text and example just below]Apparently at least one DB2 variant balks at unnamed columns for the derived table, so the query just below names the column; I chose COL1, so as to match the name from the actual TABLE, but that should not be necessary. The (col1) is added to the original query that remains from the original pre-edit version; that version remains after this edit\insertion and is missing the (col1) added here:
select *
from ( values('one'),('two'),('three'),('four') ) as x (col1)
except ( select * from table_a )
; -- report from above query follows:
COL1
three
four
The following is the original query given, for which the comment below suggests a failure for an unnamed column when run on some unstated DB2 variant; I should have noted that this SQL query functions without error, on DB2 for i 7.1
[End-Edit 05-Aug-2016]
select *
from ( values('one'),('two'),('three'),('four') ) as x
except ( select * from table_a )
; -- report from above query follows:
VALUES
three
four
I'm looking to store the results of a query that returns a list of all the unique values in a particular column, and how many times they are repeated:
SELECT col_name, COUNT(*) AS 'total' FROM dataTable GROUP BY col_name;
This returns something like:
col_name
recordA
recordB
recordC
recordD
recordE...
total
39
91817
982027
211872
256...
It's working great and exactly what I need. But I need to store the results into another table (eg. countTable) so I don't have to do the query every time, can index it... etc.
Let's say countTable has the exact same structure as the results here. Two columns: name and count of the same types as the original result.
This is going to probably raise some laughs, but currently I feel like this is close:
INSERT INTO countTable (name, count) SELECT col_name, total FROM
(SELECT col_name, COUNT(*) AS 'total' FROM dataTable GROUP BY col_name);
But I get an error: ERROR 1248 (42000): Every derived table must have its own alias
I have no idea how to wrap this query right, or if I'm supposed to use another AS somewhere?
Any help greatly appreciated!!
Thanks
You can do a SELECT right after the INSERT statement. As long as what you are selecting matches the values you want to insert (in this case name and count). You can test what will be inserted into your countTable by just running the select statement by itself.
INSERT INTO countTable (name, count)
SELECT col_name, COUNT(*) AS 'total'
FROM dataTable
GROUP BY col_name;
AH! Turns out I was very close in my original query:
INSERT INTO countTable (name, count) SELECT col_name, total FROM
(SELECT col_name, COUNT(*) AS 'total' FROM dataTable GROUP BY col_name);
I DID need to add an extra AS at the very end. Every derived table MUST indeed have its own alias :)
INSERT INTO countTable (name, count) SELECT col_name, total FROM
(SELECT col_name, COUNT(*) AS 'total' FROM dataTable GROUP BY col_name) AS count;
But it would seem I'm wrapping it unnecessarily as evidenced by spaceman's answer.
I have a simple table with two columns. The first field represents an id, the second one a name (string value). No field is unique. So, e.g., there are many records like:
What I need is a simple SQL statement which shows me the whole table in the following format and inserts the content into a new table.
Any help?
You have to use group by:
insert into tab2 (name,cnt)
select name, count(1) as cnt
from tab
group by name
Here is more informations about aggregate functions.
SQL Fiddle DEMO
Just use COUNT function to count from_id. And if you want to count in group, use GROUP BY clause for that. Like this one.
SELECT `name`, COUNT(from_id) AS `COUNT`
FROM myTable
GROUP BY `name`;
This will return your desired result.
Now you want to insert it into new table then you can do like this:
INSERT INTO newTable (`name`, `count`)
SELECT `name`, COUNT(from_id) AS `COUNT`
FROM myTable
GROUP BY `name`;
I realize this may be a really newbie question and I'm totally missin something , but I want to test out using MIN with strings (in MSSQL):
MIN('d3d742ce-f12e-4402-9a0e-8a05066f6bed',
'03f8d7a7-9feb-4375-b7ff-04c187d46009',
'1c180a55-ce67-4ab4-afe5-9d9907ed1c21' )
But it tells me:
Msg 174, Level 15, State 1, Line 5 The MIN function requires 1
argument(s).
And that makes sense to me now, but I want to do something like that if possible.
Is there a way to do something like this, without using a specific table?
What about just using a table variable
DECLARE #TABLE Table (str varchar(100))
INSERT #TABLE (str) VALUES ('d3d742ce-f12e-4402-9a0e-8a05066f6bed')
INSERT #TABLE (str) VALUES ('03f8d7a7-9feb-4375-b7ff-04c187d46009')
INSERT #TABLE (str) VALUES ('1c180a55-ce67-4ab4-afe5-9d9907ed1c21')
SELECT MIN(str) FROM #TABLE
That's it: (Works starting from SQL Server 2008)
SELECT min(id)
FROM (
VALUES
('d3d742ce-f12e-4402-9a0e-8a05066f6bed'),
('03f8d7a7-9feb-4375-b7ff-04c187d46009'),
('1c180a55-ce67-4ab4-afe5-9d9907ed1c21')) AS guids(id)
You can always create your own derived table on the fly with unions:
select min(MyCol)
from (
select 'd3d742ce-f12e-4402-9a0e-8a05066f6bed' as MyCol
union all select '03f8d7a7-9feb-4375-b7ff-04c187d46009'
union all select '1c180a55-ce67-4ab4-afe5-9d9907ed1c21'
) as MyDerivedTable
I'm using union all in this case because that's faster when you know your test data is all unique (it doesn't implicitly run as distinct like union).
This same technique can be used in a Common Table Expression (CTE):
;with CTE as (
select 'd3d742ce-f12e-4402-9a0e-8a05066f6bed' as MyCol
union all select '03f8d7a7-9feb-4375-b7ff-04c187d46009'
union all select '1c180a55-ce67-4ab4-afe5-9d9907ed1c21'
)
select min(MyCol)
from CTE
I've begun the statement with a semi-colon because SQL Server will complain if you haven't terminated the previous statement with one.
This only works to a point, however, as you can only use 256 tables in a query before having to resort to workarounds.