Strange Behaviour: SQL And operator with multiple IN operators - sql

I am using multiple IN operators with AND in my sql query where clause as given below...
---
where ID in (1, 3, 234, 2332, 2123, 989) AND tag in ('wow', 'wonderful')
But surprisingly behaviour of result seems to be of OR type rather then AND type. What I mean is it is ignoring AND operator...
Can you please explain me why?

I couldn't reproduce the result using SQL Server 2008.
SELECT * FROM
(
SELECT 0 AS ID, 'wow' as Tag
) X
WHERE ID in (1, 3, 234, 2332, 2123, 989) AND tag in ('wow', 'wonderful')
Result:
No records
SELECT * FROM
(
SELECT 1 AS ID, 'wow' as Tag
) X
WHERE ID in (1, 3, 234, 2332, 2123, 989) AND tag in ('wow', 'wonderful')
Result:
ID Tag
1 wow
Check your code again.

Related

Generating Nested XML using oracle sql XMLElement function in oracle 19c

I need to create a report but the output needs to be in XML format.
I'm following oracle docs, Example 18-3 XMLELEMENT: Generating Nested XML
https://docs.oracle.com/cd/E11882_01/appdev.112/e23094/xdb13gen.htm#ADXDB1620,
SELECT XMLElement("record",
XMLElement("PersonRegNumber", p.person_reg_number),
XMLElement("first_name", p.first_name)
) AS "record"
FROM person p
where p.id in (1, 2, 3, 4, 5);
but I'm not getting the desired output, more exactly I'm getting back (XMLTYPE)
I'm not sure what I'm doing wrong, any hints will be very appreciated.
Thanks.
You can also convert the XMLTYPE to a string if needed with the getClobVal() function:
SELECT XMLElement("record",
XMLElement("PersonRegNumber", p.person_reg_number),
XMLElement("first_name", p.first_name)
).getClobVal() AS "record"
FROM person p
where p.id in (1, 2, 3, 4, 5);

Get SQL Server column names with values

I am trying to create a query that allows me to have the column name next to its column values that it finds.
As an example:
SELECT
*
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'saverTbl'
The above returns all of the column names in that table like this:
id, Link_userTblID, type, environment, vendor, theGUID, theGUID, etc etc...
Now what I need is to get the output from the table name next to the value. This is my query to just get my values from the table:
SELECT
*
FROM
saverTbl
WHERE
LINK_userTblID = #val1
The above returns the row that matches the LINK_userTblID like so:
32, 1, 'Blah', 'something', 'Adobe', 546656156-45332-54616516-4515, etc etc..
Now putting that all together (which is what this question is all about):
id: 32,
LINK_userTblID: 1,
type: Blah,
environment: something,
vendor: Adobe,
theGUID: 546656156-45332-54616516-4515,
etc etc.....
Pretty much needing the output in a json format but the column name matching up with the columns value.
Try this:
SELECT * FROM saverTbl
WHERE LINK_userTblID = #val1
FOR JSON PATH
Assuming, this is meant for one single row you can try this:
WITH cte AS
(
SELECT
(SELECT TOP 1 * FROM sys.objects FOR XML PATH('row'),TYPE) AS TheXml
)
SELECT TheElement.value('local-name(.)','nvarchar(max)')
+ ': '
+ TheElement.value('text()[1]','nvarchar(max)') AS YourOutput
FROM cte
CROSS APPLY TheXml.nodes('/row/*') AS A(TheElement);
The result:
YourOutput
---------------
name: sysrscols
object_id: 3
schema_id: 4
parent_object_id: 0
type: S
type_desc: SYSTEM_TABLE
create_date: 2012-02-10T20:15:58.693
modify_date: 2012-02-10T20:15:58.700
is_ms_shipped: 1
is_published: 0
is_schema_published: 0
XML in connection with XQuery and XPath is a very mighty toolset to solve rather generic problems. The cte builds an XML which looks like this:
<row>
<name>sysrscols</name>
<object_id>3</object_id>
<schema_id>4</schema_id>
<parent_object_id>0</parent_object_id>
<type>S </type>
<type_desc>SYSTEM_TABLE</type_desc>
<create_date>2012-02-10T20:15:58.693</create_date>
<modify_date>2012-02-10T20:15:58.700</modify_date>
<is_ms_shipped>1</is_ms_shipped>
<is_published>0</is_published>
<is_schema_published>0</is_schema_published>
</row>
The call to /row/* retrieves all nodes below <row> as derived table. The rest is rather easy XQuery.

ST_DIFFERENCE returning GeometryCollection instead of MultiPoint

I'm trying to get the difference between two multipoints. I am doing this using the query location = ST_Difference(location, other_geo). This works when the result is not empty, however, if the two multipoints are exactly the same, the resulting object is a GeometryCollection instead of an empty MultiPoint, as would be returned from ST_geomFromText('MULTIPOINT EMPTY'). How do I get the result to be an empty multipoint object?
The following query results in a multipoint:
SELECT ST_asGeoJSON(ST_Difference(ST_geomFromText('MultiPoint(1 2, 3 4)', 4326), ST_geomFromText('MultiPoint(1 2)', 4326)));
Result: {"type":"Point","coordinates":[3,4]}
This one results in an empty GeometryCollection:
SELECT ST_asGeoJSON(ST_Difference(ST_geomFromText('MultiPoint(1 2)', 4326), ST_geomFromText('MultiPoint(1 2)', 4326)));
Result: {"type":"GeometryCollection","geometries":[]}
Try using ST_Multi and ST_CollectionExtract to always return a MultiPoint geometry with zero or more points:
SELECT ST_AsGeoJSON(ST_Multi(ST_CollectionExtract(ST_Difference(a, b), 1)))
FROM (
SELECT 'MultiPoint(1 2, 3 4)'::geometry a, 'MultiPoint(1 2)'::geometry b
UNION SELECT 'MultiPoint(1 2)', 'MultiPoint(1 2)'
) data;
st_asgeojson
---------------------------------------------
{"type":"MultiPoint","coordinates":[]}
{"type":"MultiPoint","coordinates":[[3,4]]}
(2 rows)

How to make a IN query with hstore?

I have a field (content) in a table containing keys and values (hstore) like this :
content: {"price"=>"15.2", "quantity"=>"3", "product_id"=>"27", "category_id"=>"2", "manufacturer_id"=>"D"}
I can easily select product having ONE category_id with :
SELECT * FROM table WHERE "content #> 'category_id=>27'"
I want to select all lines having (for example) category_id IN a list of value.
In classic SQL it would be something like this :
SELECT * FROM TABLE WHERE category_id IN (27, 28, 29, ....)
Thanks you in advance
De-reference the key and test it with IN as normal.
CREATE TABLE hstoredemo(content hstore not null);
INSERT INTO hstoredemo(content) VALUES
('"price"=>"15.2", "quantity"=>"3", "product_id"=>"27", "category_id"=>"2", "manufacturer_id"=>"D"');
then one of these. The first is cleaner, as it casts the extracted value to integer rather than doing string compares on numbers.
SELECT *
FROM hstoredemo
WHERE (content -> 'category_id')::integer IN (2, 27, 28, 29);
SELECT *
FROM hstoredemo
WHERE content -> 'category_id' IN ('2', '27', '28', '29');
If you had to test more complex hstore contains operations, say with multiple keys, you could use #> ANY, e.g.
SELECT *
FROM hstoredemo
WHERE
content #> ANY(
ARRAY[
'"category_id"=>"27","product_id"=>"27"',
'"category_id"=>"2","product_id"=>"27"'
]::hstore[]
);
but it's not pretty, and it'll be a lot slower, so don't do this unless you have to.
category_ids = ["27", "28", "29"]
Tablename.where("category_id IN(?)", category_ids)

SQL server query on json string for stats

I have this SQL Server database that holds contest participations. In the Participation table, I have various fields and a special one called ParticipationDetails. It's a varchar(MAX). This field is used to throw in all contest specific data in json format. Example rows:
Id,ParticipationDetails
1,"{'Phone evening': '6546546541', 'Store': 'StoreABC', 'Math': '2', 'Age': '01/01/1951'}"
2,"{'Phone evening': '6546546542', 'Store': 'StoreABC', 'Math': '2', 'Age': '01/01/1952'}"
3,"{'Phone evening': '6546546543', 'Store': 'StoreXYZ', 'Math': '2', 'Age': '01/01/1953'}"
4,"{'Phone evening': '6546546544', 'Store': 'StoreABC', 'Math': '3', 'Age': '01/01/1954'}"
I'm trying to get a a query runing, that will yield this result:
Store, Count
StoreABC, 3
StoreXYZ, 1
I used to run this query:
SELECT TOP (20) ParticipationDetails, COUNT(*) Count FROM Participation GROUP BY ParticipationDetails ORDER BY Count DESC
This works as long as I want unique ParticipationDetails. How can I change this to "sub-query" into my json strings. I've gotten to this query, but I'm kind of stuck here:
SELECT 'StoreABC' Store, Count(*) Count FROM Participation WHERE ParticipationDetails LIKE '%StoreABC%'
This query gets me the results I want for a specific store, but I want the store value to be "anything that was put in there".
Thanks for the help!
first of all, I suggest to avoid any json management with t-sql, since is not natively supported. If you have an application layer, let it to manage those kind of formatted data (i.e. .net framework and non MS frameworks have json serializers available).
However, you can convert your json strings using the function described in this link.
You can also write your own query which works with strings. Something like the following one:
SELECT
T.Store,
COUNT(*) AS [Count]
FROM
(
SELECT
STUFF(
STUFF(ParticipationDetails, 1, CHARINDEX('"Store"', ParticipationDetails) + 9, ''),
CHARINDEX('"Math"',
STUFF(ParticipationDetails, 1, CHARINDEX('"Store"', ParticipationDetails) + 9, '')) - 3, LEN(STUFF(ParticipationDetails, 1, CHARINDEX('"Store"', ParticipationDetails) + 9, '')), '')
AS Store
FROM
Participation
) AS T
GROUP BY
T.Store