Finding data patterns in sequential Postgresql rows - sql

I'd like to ask Postgres how often two occurrences of an event, one occurrence per row, are seen. For example, if I have user events like:
User 1: Clicked button 1, redirected to page 2
User 1: Clicked button 2, redirected to page 3
User 1: Clicked button 18, redirected to page 100
User 1: Clicked button 1, redirected to page 2
User 1: Clicked button 2, redirected to page 3
then I would see the pattern ((button 1, page 2) => (button 2, page 3)) counted as two occurances.
Is this possible, and if so, how?

It's a very good question and has a fairly simple solution. Use GROUP BY and HAVING to find out which user shows what sort of repeated behavior.
Please see the fiddle example here which discusses the DDL and the query I have used to get the desired result.
From your description I recommend you create a table for storing user events as follows:
CREATE TABLE t_clickevent (
clickevent_id INTEGER,
user_id INTEGER,
clicked_button_id INTEGER,
redirected_url_id INTEGER);
Add any more columns as and when you require. This is just a minimal structure.
Use the query as follows:
SELECT user_id, clicked_button_id,
redirected_url_id
FROM t_clickevent
GROUP BY user_id, clicked_button_id,
redirected_url_id
HAVING count(*) > 1;
Output:
USER_ID CLICKED_BUTTON_ID REDIRECTED_URL_ID
----------- --------------------- -----------------
1 1 2
1 2 3
Cheers!

Related

DataStudio ::: Count_Distinct Calculation based on two values

I have a data set with two values. The first being User ID, the second being Type.
I previously had a count_distinct on the user ID. However, if a user changes their Type, the metrics we have to show 'Type' of user shows two instances of that once unique user.
I would like some SQL which basically states if the User ID and Type Match, then count that as a unique user. If either one of those change, count that also as a unique user. So that..
1) Jane Doe - Support User
2) Jane Doe - Employee User
3) John Smith - Support User
This would show as 3 unique users, rather than 2 based on a count_unique on just the User ID.
One way to accomplish this is with a calculated field that looks something like the following:
COUNT_DISTINCT(CONCAT(USER_ID, ' - ', TYPE))
You might need to replace USER_ID and TYPE with your field names.

How to set number of copies for every page by value in Ireport?

Is it possible to set number of copies for page?
For example:
SELECT NAME, TYPE, QUANTITY FROM INFORMATIONS
SQL result:
Tom | house | 2
Mark| cars | 3
One page is for Tom and second page is for Mark.
Can i write SQL that will output me that many results as i want. (some for loop?)
I want to see in preview 2 pages for Tom(copies) and 3 pages for Mark. (5 pages to print)
Please, if you can past me sample code or pictures how to do it.
If you want to generate rows based on the quantity, you can do:
select i.*, generate_series(1, i.quantity) as n
from informations i;
This seems to be what you asking.

SQL query to turn audit trail in / out times to list of locations

I have a database that is used to track the location of physical objects, lets call them widgets. It has an audit trail table that tracks when a widget is put in a location, and when it leaves a location (and where it went after that).
So conceptually it looks like this
Widget ID Date Old Location New Location
1 01-Oct-2013 NULL 101
1 03-Oct-2013 101 108
1 08-Oct-2013 108 101
2 01-oct-2013 NULL 101
2 02-Oct-2013 101 103
3 12-oct-2013 NULL 101
I want to be able to query a list of which widgets were in location 101 between a start and end date, such as 08-09 Oct 2013, this should be widget 1 but not widget 2 or 3.
I'm not sure how to get all these cases. I can pull a list of widget's that were moved in before the end, and a list of widgets that were moved out before the start, but that would also eliminate widget 1 as it leaves and comes back.
I think I need to convert this to a table with widget, location, entry date and exit date, but I'm not sure how to do that ?
EDIT: As pointed out, My data was wrong, I've updated to make the question the 8th to 9th (it was the 4th to 5th). So Widget 1 is the only widget in location 101 in that period.
Try something like this:
select *
from
(select "Widget ID" id,
"New Location" loc,
"Date" start_date,
lead("Date", 1, sysdate) over (partition by "Widget ID" order by "Widget ID") end_date
from widgets) t
where t.loc = 101
and start_date < <<your_ending_date>> and end_date > <<your_starting_date>>
here is a sqlfiddle demo (note that I changed you data a little bit)
So you need last state of each widget within period.
Probably need subselect statement that selects all widgets between dates, groups them by id, orders by Date desc, selects top 1, so you know widget's last state within the period.
UPDATE according to new conditions
I want to know if the widget was in the location at any time during
the period
You make select with distinct IDs and a subselect with EXISTS that checks if the row with the current ID and date within period and new location = X presents in resultset. This will make you know what items came to store at least 1 time.

GridView Blank On Pagination

I have no problem getting a GridView or ListView to page, normally. If I use Sql datasource and I use a query like:
SELECT RecipeName FROM PostedRecipes
and I enter Hot Dog, for example, in a search text box, and there are 40 Hot Dog recipes, the GridView/ListView will show page 1 with 10 recipes (if the count is set to 10) and show that there are 3 more pages to go. Each page then, page 2 or 3 or 4, will show additional recipes. However,
If I use a query like:
SELECT RecipeName FROM PostedRecipes
WHERE RecipeName LIKE '%' + #RecipeName + '%' GROUP BY RecipeName
and I make the same search entry, the GridView will show page 1 with 10 recipes and indicate that there are 3 more pages. BUT, if I click on page 2 or 3 or 4, a blank page is then displayed.
If I set the count to 40, all 40 recipes will be displayed on the initial search - which would indicate that all the recipes are being retrieved from the database. I am not sure if this is some sort of GridView problem or a postback problem of some sort. Any help would be appreciated.

SQL filter search according to multiple column values

I am dealing with one table(3+ million rows,SQL Server)
I need to filter results according to the two columns below:
<code>
...FromID| ToID |Column5|....
...1001 2001
...1002 2020
...1003 5000
...1001 3000
...2001 1001
</code>
Now User1 can access records with FromID or ToId 1001.
FromID|ToID
1001|2001
1001|3000
2001|1001
User2 can access records with FromID or ToID 1002,1003,3000
FromID|ToID
1002|2020
1003|5000
1001|3000
What is the most efficient way to do this ?
Do i need to create a view for each user ?(this is working on enterprise,user count will be
max 100 )
Thanks.
PS. My very first question. O.o
Your access criteria seem to be fairly arbitrary. User1 gets 1001, user2 gets 1002, 1003, and 3000, and I assume users 3 through 99 have arbitrary access as well. In that case, I recommend that you create a table, call it useraccess for this example:
user |accessID
---------------
user1|1001
user2|1002
user2|1003
user2|3000
... |...
Now when you want to know what rows a user has, you can do this:
SELECT t.FromID, t.ToID, [[other columns you care about]]
FROM yourtable t
JOIN useraccess a ON t.FromID = a.accessID OR t.ToID = a.accessID
WHERE a.user = 'user2'
You can either run that query dynamically or you can create a view based on it. The usual tradeoffs between views and direct queries will apply as usual.
Edit: I just saw your note that you already have a UserRights table, so you already have step 1 completed.