I'm new in KDB and struggling with creating a query. Will appreciate any help.
I have a table of strings and need to get the count of all specific substrings across all strings in the table.
So, let's assume that I have strings:
[
string1: Apple is green, cherry is red,
string2: Ququmber is green, banana is yellow
]
and I want to get a count of "Apple" and "green" across all substrings. My desired result is to have a grouping like so:
{
Apple: 1,
green: 2
}
But, unfortunately, I have no idea how to make such a grouping. I have already figured out how to get strings that contain at least one of the needed substrings:
"select count(text) from data where any text like/: (\"*$Apple*\";\"*$green*\")"
but that returns me the cumulative result of all found strings for Apple and green without any grouping:
{
text: 3
}
which does not allow differentiating the amount of each particular substring.
I will be really thankful for any help.
Instead of using a where clause with an any, you can put the like/: in the select phrase to get a nested list of booleans where each list represents the matches for one search string. Then you can just sum these to get the total matches for each search string. I've used an exec here rather than a select as I suspect that output will be more useful:
q)t:([] text:("Apple is green, cherry is red,";"Ququmber is green, banana is yellow"))
q)exec sum each text like/:("*Apple*";"*green*") from t
1 2i
You could use -4! to count the frequency of every substring
q)t:([] text:("Apple is green, cherry is red,";"Ququmber is green, banana is yellow"))
q)count each group exec raze -4!'text from t
"Apple" | 1
," " | 10
"is" | 4
"green" | 2
,"," | 3
"cherry" | 1
"red" | 1
"Ququmber"| 1
"banana" | 1
"yellow" | 1
I have this table
itemname property value
------------------------------------------
A size big
A color red
B size big
B color blue
C size small
C color blue
D size small
D color blue
E size small
E color blue
Im creating a list like this: SELECT property,value,COUNT(itemname),GROUP_CONCAT(itemname) FROM table GROUP BY property,value
property value count
---------------------------------
size big 2 (A,B)
size small 3 (C,D,E)
color red 1 (A)
color blue 4 (B,C,D,E)
I want to filter the items which are BIG && SMALL && BLUE, how can i achieve this result ? (I MUST be specific about the property when addressing a value for filtering)
`SELECT
property,value,COUNT(itemname),GROUP_CONCAT(itemname)
FROM
table
GROUP BY
property,value
HAVING
( property IN ('size') && value IN ('big','small') )
&&
( property IN ('color') && value IN ('blue') )`
But this has no result, because it tries to match the row with size and color at the same time ? My desired output in this case is to avoid the item A because it is red, like this:
property value count
---------------------------------
size big 1 (B) A not here, because it is red
size small 3 (C,D,E) no change because all are blue
color red 0 (A) no red is selected, so this row should be 0 or not listed at all
color blue 4 (B,C,D,E) all the 4 are big or small and blue
Please someone help me out in this, i lost 2days wondering on the solution.
I might use CASE combined with HAVING ? Or i should address the WHERE instead somehow ?
Note: This table is actually not real, but if this question can be solved i can use it in my real tables which are a lot more complicated.
I figured a solution on my own, of course this example table is nonsense, the point is the way it had been solved.
`
SELECT
property,
value,
COUNT(t.itemname) AS count
FROM (
SELECT
itemname
FROM
table
GROUP BY
itemname
HAVING
COUNT (CASE WHEN property='size' AND value IN ('big','small') THEN 1 END) >=1
&&
COUNT (CASE WHEN property='color' AND value IN ('blue') THEN 1 END) >=1
) t
INNER JOIN
table ON table.itemname=t.itemname
GROUP BY
property,value
`
I have a 2 tables FIRST
id,rl_no,adm_date,fees
1,123456,14-11-10,100
2,987654,10-11-12,30
3,4343,14-11-17,20
and SECOND
id,rollno,fare,type
1,123456,20,bs
5,634452,1000,bs
3,123456,900,bs
4,123456,700,bs
My requirement is twofold,
1, i first need to get all columns from both tables with common rl_no. So i used:
SELECT a.ID,a.rl_no,a.adm_date,a.fees,b.rollno,b.fare,b.type FROM FIRST a
INNER JOIN
SECOND b ON a.rl_no = b.rollno
The output is like this:
id,rl_no,adm_date,fees,rollno,fare,type
1,123456,14-11-10,100,123456,20,bs
1,123456,10-11-12,100,123456,900,bs
1,123456,14-11-17,100,123456,700,bs
2,Next i wanted to get the sum(fare) of those rollno that were common between the 2 tables and also whose fare >= fees from FIRST table group by rollno and id.
My query is:
SELECT x.ID,x.rl_no,,x.adm_date,x.fees,x.rollno,x.type,sum(x.fare) as "fare" from (SELECT a.ID,a.rl_no,a.adm_date,a.fees,b.rollno,b.fare,b.type FROM FIRST a
INNER JOIN
SECOND b ON a.rl_no = b.rollno) x, FIRST y
WHERE x.rollno = y.rl_no AND x.fare >= y.fees AND x.type IS NOT NULL GROUP BY x.rollno,x.ID ;
But this is throwing in exceptions.
ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
The expected output will be like this:
id,rollno,adm_date,fare,type
1,123456,14-11-10,1620,bs
So could someone care to show an oracle newbie what i'm doing wrong here?
It looks like there's a couple different problems here;
Firstly, you're trying to group by an x.ID column which doesn't exist; it looks like you'll want to add ID to the selected columns in your sub-query.
Secondly, when aggregating with GROUP BY, all selected columns need to be either listed in the GROUP BY statement or aggregated. If you're grouping by rollno and ID, what do you want to have happen to all the extra values for adm_date, fees, and type? Are those always going to be the same for each distinct rollno and ID pair?
If so, simply add them to the GROUP BY statement, ie,
GROUP BY adm_date, fees, type, rollno, ID
If not, you'll need to work out exactly how you want to select which one to be output; If you've got output like your example (adding in an ID column here)
ID,adm_date,fees,rollno,fare,type
1,14-11-10,100,123456,20,bs
1,10-11-12,100,123456,900,bs
1,14-11-17,100,123456,700,bs
Call that result set 'a'. If I run;
SELECT a.ID, a.rollno, SUM(a.fare) as total_fare
FROM a
GROUP BY a.ID, a.rollno
Then the result will be a single row;
ID,rollno,total_fare
1,123456,1620
So, if you also select the adm_date, fees, and type columns, oracle has no idea what you mean to do with them. You're not using them for grouping, and you're not telling oracle how you want to pick which one to use.
You could do something like
SELECT a.ID,
FIRST(a.adm_date) as first_adm_date,
FIRST(a.fees) as first_fees,
a.rollno,
SUM(a.fare) as total_fare,
FIRST(a.type) as first_type
FROM a
GROUP BY a.ID, a.rollno
Which would give the result;
ID,first_adm_date,first_fees,rollno,total_fare,first_type
1,14-11-10,100,123456,1620,bs
I'm not sure if that's what you mean to do though.
I have got a database and a table inside it. Here my table:
Houses (
id,
doors,
windows,
bathrooms,
wallColor,
dateRent
)
I want to compare data os this table and get if it is equal or not: For example:
Select id, doors, windows, bathrroms, wallColor
from Houses
where dateRent='01-02-2013' equal(
Select id, doors, windows, bathrroms, wallColor
from Houses
where dateRent='08-09-2014'
);
It just be great to give me true or false.
This will return the duplicated houses or no rows if none
select id, doors, windows, bathrroms, wallColor
from Houses
where dateRent in ('01-02-2013', '08-09-2014')
group by 1, 2, 3, 4, 5
having count(*) > 1
If you want to always return a single row with the true or false value:
with q as (
select id, doors, windows, bathrroms, wallColor
from Houses
where dateRent in ('01-02-2013', '08-09-2014')
group by 1, 2, 3, 4, 5
having count(*) > 1
)
select exists (select 1 from q) as equal;
Depending on the server configuration you will need to use the ISO date format YYYY-MM-DD or another one.
BTW are you sure you want to include the id in the comparison? That looks like a primary key.
I would do that with a join
SELECT DISTINCT houses1.id, coalesce(houses2.id, 'No Match') as Matched
FROM Houses h1
LEFT JOIN Houses h2 on h1.id=h2.id
AND h1.doors=h2.doors
AND h1.windows=h2.windows
AND h1.bathrooms=h2.bathrooms
AND h1.wallColor=h2.wallColor
AND h2.dateRent='08-09-2014'
WHERE h1.dateRent='01-02-2013'
this will get you the house id of each house in the first date, and compare if there's at least a house in the second date with the same number of doors, windows, bathrooms and wallcolor
it won't return true or false, but instead the matching ID or 'No Match' if there isn't.
But if there can be more than one house per date, then a single true or false won't help you. You will always need the id field.
Need some stack overflow love. Read the other questions related to group by and sort by and those answers don't seem to work for me. I am not really strong in the finer details of db statements and think there is some dependency or conflict between group and order by statements I am missing.
I have a table (itemOptions) that holds all the options of an item and all the possible values for those options. Think multiple select/drop down boxes for an item and the list of values for each drop down. And unfortunately I can't change the db structure, as a web service is providing the sqlite file.
Here's the structure:
absTtemId optionName optionPosition valueName valuePosition
item1 size 1 small 1
item1 size 1 medium 2
item1 size 1 large 3
item1 color 2 white 1
item1 color 2 red 2
item1 color 2 yellow 3
item2 name 1 willis 1
item2 name 1 smith 2
item2 name 1 bowman 3
The query needs to return optionsNames for a given item ordered by optionPosition, and then a list of valueNames for each option ordered by valueposition, like this
option valueNames
size small, medium, large
color white, red, yellow
I am able to get the grouping of valueNames by option to work, but when I try to add sorting anywhere, sqlite throws errors.
Here's my current sql statement that returns these results, however option and valueNames are never in order.
SELECT optionName, group_concat(valueName)
FROM itemOptions
WHERE absItemId = 'item1'
GROUP BY optionName
option valueNames
size medium, small, large
color yellow, red, white
Here's some of my failed attempts at adding sorting for valueName and optionName
SELECT optionName, group_concat(valueName ORDER BY valuePosition DESC)
FROM itemOptions
WHERE absItemId = 'item1'
GROUP BY optionName
EDIT: sporting for optionName grouping is working now with this. Only valueName sorting within the group_concat not working.
SELECT optionName, group_concat(valueName)
FROM itemOptions
WHERE absItemId = 'item1'
GROUP BY optionName
ORDER BY optionPosition
try
SELECT a.optionName, group_concat(a.valueName)
FROM (SELECT * FROM itemOptions ORDER BY valuePosition ASC) As a
WHERE a.absItemId = 'item1'
GROUP BY a.optionName
ORDER BY a.optionName