How I can get last column based on the "competition" and "user" columns? the following query gives error!
SELECT DISTINCT COUNT(*) AS countofcomments
FROM k
GROUP BY competition, user
I don't know is that a good practice you trying to achieve, On considering the result set you can try something like this
CREATE TABLE #Example(
[competition] [nvarchar](50) NULL,
[user] [nvarchar](50) NULL,
[comments] nvarchar(50) NOT NULL,
)
GO
INSERT #Example ([competition],[user], [comments]) VALUES ('INDIA','CHENNAI','ssss')
INSERT #Example ([competition],[user], [comments]) VALUES ('INDIA','KOCHI','ssss')
INSERT #Example ([competition],[user], [comments]) VALUES ('INDIA','BANGLORE','ssss')
INSERT #Example ([competition],[user], [comments]) VALUES ('INDIA','HYDERABAD','ssss')
INSERT #Example ([competition],[user], [comments]) VALUES ('US','MAIAMI','ssss')
INSERT #Example ([competition],[user], [comments]) VALUES ('US','SANFRANC','ssss')
INSERT #Example ([competition],[user], [comments]) VALUES ('US','MOUNT','ssss')
INSERT #Example ([competition],[user], [comments]) VALUES ('US','LOSANGELS','ssss')
INSERT #Example ([competition],[user], [comments]) VALUES ('UK','MANCHESTER','ssss')
INSERT #Example ([competition],[user], [comments]) VALUES ('UK','CHELSEA','ssss')
SELECT * from (
SELECT * FROM #Example
) tab1 join
(
SELECT [competition] , count([comments] )count FROM #Example
group by [competition]
) tab2 on tab1.[competition]= tab2.[competition]
DROP table #Example
You can do this using window function:
SELECT *, COUNT(*) OVER(PARTITION BY competition, user) as [Count of comments]
FROM k
Related
Background: I am building a Springboot+mySQL app that uses Spring Data JPA native queries (i.e. #Query(value = "...", nativeQuery = true) to retrieve database data.
We have to use the same SQL in every query we write to enable certain functionality (this can be seen in the example below). And wanted a way to remove this duplicate SQL and instead only declare it once. An option presented was to pass a dynamic SQL string into a stored procedure and then build a prepared statement by concatenating this dynamic SQL string with our static shared SQL string (show in example below).
Question:
This doesn't seem like a good idea to me, but I am not knowledgeable enough about databases to given the exact technical reasons. Is the below example safe, reasonable, and best-practice? Are there ways to mitigate issues with this approach, or are there other approaches to use instead?
Basic setup code:
-- create tables
CREATE TABLE docs (
id INTEGER PRIMARY KEY,
rev INTEGER NOT NULL,
content VARCHAR(30) NOT NULL
);
CREATE TABLE more_docs (
id INTEGER PRIMARY KEY,
more_content VARCHAR(30) NOT NULL
);
CREATE TABLE docs_metadata (
id INTEGER PRIMARY KEY,
letter VARCHAR(30) NOT NULL
);
CREATE TABLE metadata_nums (
id INTEGER PRIMARY KEY,
metadata_id INTEGER,
num INTEGER NOT NULL
);
-- insert some values
INSERT INTO docs VALUES (1, 1, 'abc');
INSERT INTO docs VALUES (2, 1, 'def');
INSERT INTO docs VALUES (3, 2, 'ghi');
INSERT INTO docs VALUES (4, 1, 'jkl');
INSERT INTO more_docs VALUES (1, 'aaa');
INSERT INTO more_docs VALUES (2, 'bbb');
INSERT INTO more_docs VALUES (3, 'ccc');
INSERT INTO more_docs VALUES (4, 'ddd');
INSERT INTO docs_metadata VALUES (1, 'a');
INSERT INTO docs_metadata VALUES (2, 'b');
INSERT INTO docs_metadata VALUES (3, 'c');
INSERT INTO docs_metadata VALUES (4, 'd');
INSERT INTO metadata_nums VALUES (1, 1, 5);
INSERT INTO metadata_nums VALUES (2, 1, 6);
INSERT INTO metadata_nums VALUES (3, 2, 5);
INSERT INTO metadata_nums VALUES (4, 2, 6);
INSERT INTO metadata_nums VALUES (5, 3, 5);
INSERT INTO metadata_nums VALUES (6, 3, 6);
INSERT INTO metadata_nums VALUES (7, 4, 5);
INSERT INTO metadata_nums VALUES (8, 4, 6);
Approach in question:
-- create stored procedure
DELIMITER //
CREATE PROCEDURE FILTER_EVAL (IN dynamic_statement TEXT, IN num INT, IN letter VARCHAR(1))
BEGIN
SET #dynamic_statement := CONCAT("SELECT X.* FROM (", dynamic_statement, ") X INNER JOIN (SELECT DM.*, MN.num FROM docs_metadata DM INNER JOIN metadata_nums MN ON DM.id = MN.metadata_id) M ON X.id = M.id WHERE M.num = ", num, " AND M.letter = '", letter, "'");
PREPARE prepared_statement FROM #dynamic_statement;
EXECUTE prepared_statement;
DEALLOCATE PREPARE prepared_statement;
END//
DELIMITER ;
-- fetch some values
CALL FILTER_EVAL("SELECT * FROM docs WHERE rev = 1", 5, 'b')
Can insert into table * number with same data in Mysql?(Yes, have same value 3 or 100 times)
INSERT INTO `test`(`name`, `test1`, `other_status`, `status`)
VALUES ('string', 'KPrBf9', 1, 0) * 3;
You need a stored procedure to insert same statement multiple times:
DELIMITER $$
CREATE PROCEDURE insert_loop ( IN nr_input bigint)
BEGIN
DECLARE counter BIGINT DEFAULT 0;
my_loop: LOOP
SET counter=counter+1;
IF counter=nr_input THEN
LEAVE my_loop;
END IF;
INSERT INTO `test`(`name`, `test1`, `other_status`, `status`)
VALUES ('string', 'KPrBf9', 1, 0);
END LOOP my_loop;
END$$
DELIMITER ;
Above procedure will insert same values based on the input parameter you give.
Call the procedure by using:
call insert_loop(5); ---number of rows to be inserted
Not sure what do you mean by *3
But if you want to insert multiple records you can use the following
INSERT INTO `test`(`name`, `test1`, `other_status`, `status`)
VALUES ('string', 'KPrBf9', 1, 0),
('string', 'KPrBf9', 1, 0),
('string', 'KPrBf9', 1, 0);
Forget about INSERT .. VALUES and study INSERT .. SELECT .
INSERT INTO table_name (columns_names) -- (`name`, `test1`, `other_status`, `status`)
WITH RECURSIVE cte AS (
SELECT 1 AS amount
UNION ALL
SELECT amount + 1 FROM cte WHERE amount < #amount_of_rows_to_insert
)
SELECT 'values list' -- 'string' AS name, 'KPrBf9' AS test1, 1 AS other_status, 0 AS status
FROM cte;
If MySQL version is too old and does not support CTE then
INSERT INTO table_name (columns_names)
SELECT 'values list'
FROM ( SELECT 1 AS amount UNION ALL
SELECT 2 UNION ALL
-- ...
SELECT #amount_of_rows_to_insert ) AS cte;
My example code:
SET #VARIABLE1 := 'Heyho';
create table Test(id integer, title varchar(100));
insert into Test(id, title) values(1, "Hello");
insert into Test(id, title) values(2, (SELECT #VARIABLE1));
insert into Test(id, title) values(3, (SELECT #VARIABLE2 WHERE #VARIABLE2 IS NOT NULL));
select * from Test;
My actual results:
id title
1 Hello
2 Heyho
3 NULL
My expected results:
id title
1 Hello
2 Heyho
I only want to insert my row with ID 3 if the #VARIABLE2 Is not null
Due to Akina's comment the correct code is:
SET #VARIABLE1 := 'Heyho';
create table Test(id integer, title varchar(100));
insert into Test(id, title) values(1, "Hello");
insert into Test(id, title) SELECT 2, #VARIABLE1 WHERE #VARIABLE1 IS NOT NULL;
insert into Test(id, title) SELECT 3, #VARIABLE2 WHERE #VARIABLE2 IS NOT NULL;
select * from Test;
It works now, I get the expected results!
CREATE TABLE #T ( DateColumn DATE, SomeColA VARCHAR (20), Temp INT,
Attribute1 VARCHAR (10), Attribute2 VARCHAR (10) )
INSERT INTO #T VALUES ('20180101', 'A', 8, 'D', NULL)
INSERT INTO #T VALUES ('20180201', 'B', 10, NULL, 'A')
INSERT INTO #T VALUES ('20180301', 'B', 12, NULL, NULL)
INSERT INTO #T VALUES ('20180401', 'A', 14, 'D', 'C')
INSERT INTO #T VALUES ('20180501', 'A', 15, 'E', 'Y')
SELECT DateColumn,
SomeColA,
Temp,
Attribute1,
Attribute2
-- INTO #NewTable
FROM #T FOR JSON AUTO
Now I've read on several pages that this is not possible. What those pages do not include however, is how this does work.
Must be quite simple, but I can't find it.
Thanks a lot!
JSON
SQL Server (starting with 2016)
https://learn.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server?view=sql-server-2017
or upper db compatibility level to 130
Store a query as a JSON object use CTE, for example
;WITH x(a) as
(
SELECT DateColumn,
SomeColA,
Temp,
Attribute1,
Attribute2
FROM #T FOR JSON AUTO
)
SELECT a INTO #b FROM x
I just do this and it gives me json result.
;WITH x(a) as
(
SELECT
PatientId,
LName
FROM tblpatientmaster FOR JSON AUTO
)
--select * from x
SELECT a INTO #temp FROM x
select * from #temp
[{"PatientId":1,"LName":"Doe"},{"PatientId":2,"LName":"Doe"},{"PatientId":5,"LName":"Kirk"},{"PatientId":6,"LName":"Doe"},{"PatientId":7,"LName":"Dasddsa"},{"PatientId":8,"LName":"Azelia"},{"PatientId":9,"LName":"Patient"},{"PatientId":10,"LName":"Smith"},{"PatientId":11,"LName":"Brothers"},{"PatientId":12,"LName":"TtEE"},{"PatientId":13,"LName":"Tes"},{"PatientId":14,"LName":"Hernandez"},{"PatientId":15,"LName":"Velazquez"},{"PatientId":16,"LName":"Spock"},{"PatientId":17,"LName":"Patient"},{"PatientId":18,"LName":"Doe"},{"PatientId":20,"LName":"Doe"},{"PatientId":22,"LName":"Doe"},{"PatientId":23,"LName":"Doe"},{"PatientId":24,"LName":"Doe"}]
Remove the '#' in the Name Table
Example:
CREATE TABLE #T ( DateColumn DATE, SomeColA VARCHAR (20), Temp INT,
Attribute1 VARCHAR (10), Attribute2 VARCHAR (10) )
Live Demo:
http://sqlfiddle.com/#!18/2d6f9/2
Output:
[{"DateColumn":"2018-01-01","SomeColA":"A","Temp":8,"Attribute1":"D"},
{"DateColumn":"2018-02-01","SomeColA":"B","Temp":10,"Attribute2":"A"},
{"DateColumn":"2018-03-01","SomeColA":"B","Temp":12},{"DateColumn":"2018-04-01","SomeColA":"A","Temp":14,"Attribute1":"D","Attribute2":"C"},
{"DateColumn":"2018-05-01","SomeColA":"A","Temp":15,"Attribute1":"E","Attribute2":"Y"}]
Following the posting,
TSQL Variable With List of Values for IN Clause
I formed a table variable of varchar, e.g.
Declare #myList_1(Id varchar(2))
Insert into #myList_1
Select id from (VALUES ('x1')) AS tbl(id)
Insert into #myList_1
Select id from (VALUES ('x2')) AS tbl(id)
Insert into #myList_1
Select id from (VALUES ('x3')) AS tbl(id)
However, I need to extend this concept so that I can do something such as a "like comparison"
e.g.:
myTable.myCol like ('%' + #myList_1 + '%')
above: SSMS 2008 r2 gives error: 'Must declare the scalar variable #myList_1'
If possible, I'd like to do this without an iterator or looping construct ...
Let's assume following testing data and tables structure.
-- Create test table
CREATE TABLE [dbo].[myTable](
[Id] [int] NOT NULL PRIMARY KEY,
[myCol] [varchar](100) NULL)
GO
-- Insert test data
INSERT INTO myTable(Id, myCol)
VALUES (1, 'Bladder cancer'),
(2, 'Lung cancer'),
(3, 'Brain cancer'),
(4, 'Melanoma'),
(5, 'Breast cancer'),
(6, 'Non-Hodgkin lymphoma'),
(7, 'Cervical cancer'),
(8, 'Ovarian cancer'),
(9, 'Cardiovascular disease'),
(10, 'Nerve damage'),
(11, 'Kidney damage'),
(12, 'Eye damage'),
(13, 'Foot damage'),
(14, 'Skin conditions'),
(15, 'Alzheimer''s disease'),
(16, 'Hearing impairment')
GO
Now the actual SQL would be based on joining the table where you want to do search with table variable #myList_1
-- Create list of items to look for
Declare #myList_1 table(Id varchar(20))
Insert into #myList_1
Select id from (VALUES ('cancer')) AS tbl(id)
Insert into #myList_1
Select id from (VALUES ('Melanoma')) AS tbl(id)
Insert into #myList_1
Select id from (VALUES ('lymphoma')) AS tbl(id)
-- Do query
SELECT myTable.Id, myTable.myCol
FROM myTable
JOIN #myList_1 as ItemsList
ON myTable.myCol like '%' + ItemsList.Id + '%'
In this simple case where myCol could match just single value in the #myList_1 this should be enough, but for cases where possible that myCol could match multiple values in the #myList_1 you should add DISTINCT to the query
-- Do query
SELECT DISTINCT myTable.Id, myTable.myCol
FROM myTable
JOIN #myList_1 as ItemsList
ON myTable.myCol like '%' + ItemsList.Id + '%'