How can I query max date? (PostgreSQL) - sql

Using PostgreSQL, I would like to be able to only see Document IDs with the latest modification time stamp. I am having difficulty getting this working and was wondering if anyone had any pointers?
Here is my current code:
SELECT cmsdw_document.document_id as "Document ID",
cmsdw_activity_meta.activity_name as "Activity Name",
cmsdw_document.title as "Title",
cmsdw_document.creation_ts as "Creation Timestamp",
cmsdw_document.modification_ts as "Modification Timestamp",
cmsdw_user.firstname as "First Name",
cmsdw_user.lastname as "Last Name",
cmsdw_container.name as "Name",
cmsdw_document_stats_fact.content_id as "Content ID",
cmsdw_document_stats_fact.views as "Views",
cmsdw_document_stats_fact.likes as "Likes",
cmsdw_document_stats_fact.bookmarks as "Bookmarks",
cmsdw_document_stats_fact.comments as "Comments",
cmsdw_document_stats_fact.shares as "Shares",
cmsdw_document_stats_fact.unique_viewers as "Unique Viewers"
FROM
public.cmsdw_document,
public.cmsdw_document_stats_fact,
public.cmsdw_container,
public.cmsdw_object,
public.cmsdw_user,
public.cmsdw_activity_fact,
public.cmsdw_activity_meta
WHERE
cmsdw_activity_fact.activity_type = cmsdw_activity_meta.activity_type AND
cmsdw_document_stats_fact.content_id = cmsdw_object.object_id AND
cmsdw_document.document_id = cmsdw_object.object_id AND
cmsdw_container.container_id = cmsdw_document.container_id AND
cmsdw_object.dw_object_id = cmsdw_activity_fact.direct_dw_object_id AND
cmsdw_object.object_type = cmsdw_activity_fact.direct_object_type AND
cmsdw_activity_fact.user_id = cmsdw_user.user_id AND
cmsdw_container.name = 'Getting Started' AND
cmsdw_object.object_type = 102 AND
cmsdw_activity_fact.activity_type = 20;

You should fix your query to have proper join syntax -- simple rule: never use commas in the from clause.
For your query, you can replace the select with with:
select distinct on (cmsdw_document.document_id) . . .
The ". . ." is the rest of your query. Then add:
order by cmsdw_document.document_id, cmsdw_document.modification_ts desc
This should give you the latest document, using a Postgres extension.

Related

Delete or ignore rows that have empty tables when using Table.ExpandTableColumn | Power Query

I need to expand a table column but some of the table contents are empty and return ""
when I run the query it stops at the first table where the content is empty.
I need to ignore these rows when using the Table.ExpandTableColumn or delete them beforehand.
#"Função Personalizada Invocada" = Table.AddColumn(#"Tipo Alterado", "generation_24hrs", each get_generation_24([user.data.id])),
#"generation_24hrs Expandido" = Table.ExpandTableColumn(#"Função Personalizada Invocada", "generation_24hrs", {"entry.value.id", "entry.value.kwh_ger", "entry.value.kwh_con"}, {"entry.value.id", "entry.value.kwh_ger", "entry.value.kwh_con"})
Before
After:
try
#"Função Personalizada Invocada" = Table.AddColumn(#"Tipo Alterado", "generation_24hrs", each get_generation_24([user.data.id])),
#"Added Custom" = Table.AddColumn(#"Função Personalizada Invocada", "RowCount", each Table.RowCount([generation_24hrs])),
#"Filtered Rows" = Table.SelectRows(#"Added Custom", each ([RowCount] <> "0")),
#"generation_24hrs Expandido" = Table.ExpandTableColumn(#"Filtered Rows", "generation_24hrs", {"entry.value.id", "entry.value.kwh_ger", "entry.value.kwh_con"}, {"entry.value.id", "entry.value.kwh_ger", "entry.value.kwh_con"})

How to make multiple SELECT queries at once in PostgreSQL?

Update: See the "Update" section below for the latest.
I have been working with Knex.js to build SQL queries in Node.js, and have the following code. This code works on a sort of graph data model (nodes and links), where there is a links table which has everything (links link to links). Given this code, I am wondering how I can make it one query instead of one query per attribute which is how it is now. The getTableName() function returns a string_links table for string values, and <x>_links tables for the other datatypes, while the "basic" links table is just called links.
Essentially how this works is, first query the top level where the parent_id is equal to some "type" ID, say we are querying "user" objects, the type would be "user". So let instance = ... is getting all the instance links from this user type. Then we go through each field of a query (a query for now is just boolean-valued map, like { email: true, name: true }). For each field of the query, we make a query to find all those nodes, linked off the instance, as so-called property links.
There are two types of properties, but don't need to go into too much detail on that. Essentially there are complex properties with audit trails and simple properties without audit trails. That is what is meant by the interactive branch in the logic.
How can I make this into one SQL query? The SQL query it prints out for an example is like this:
select "id" from "links" where "parent_id" = '47c1956bz31330c' and "name" = 'link' limit 1
select "value" from "string_links" where "parent_id" = (select "value" from "links" where "parent_id" = '47c1956bz31330cv' and "name" = 'name' limit 1) and "name" = 'value' limit 1
select "value" from "text_links" where "parent_id" = (select "value" from "links" where "parent_id" = '47c1956bz31330cv' and "name" = 'website' limit 1) and "name" = 'value' limit 1
select "value" from "integer_links" where "parent_id" = (select "value" from "links" where "parent_id" = '47c1956bz31330cv' and "name" = 'revenue' limit 1) and "name" = 'value' limit 1
select "value" from "boolean_links" where "parent_id" = '47c1956bz31330' and "name" = 'verified' limit 1
The original Node.js for Knex.js is here, but really I'm just concerned with how to write this as one regular SQL query, and I can figure out how to make it in Knex.js from there:
async function selectInteractiveInstance(user, name, query) {
const type = model.types[name]
const typeId = await baseSchemaController.selectType(name)
let instance = await knex.from(`links`)
.select('id')
.where('parent_id', typeId)
.where('name', 'instance')
.first()
// { id: 123, props: { ... } }
instance.props = {}
for (let field in query) {
let data = query[field]
let attrSchema = type[field]
const tableName = baseSchemaController.getTableName(attrSchema.type)
if (attrSchema.interactive) {
const query1 = knex
.from(`links`)
.select('value')
.where('parent_id', instance.link)
.where('name', field)
.first()
const record = await knex
.from(tableName)
.select('value')
.where('home', query1)
.where('name', 'value')
.first()
if (record) {
instance.props[field] = record.value
}
} else {
const record = await knex
.from(tableName)
.select('value')
.where('parent_id', instance.id)
.where('name', field)
.first()
if (record) {
instance.props[field] = record.value
}
}
}
return instance
}
The reason for asking is because the number of queries of this function is equal to the number of properties on the object, and I would like to avoid that, but not really that great at SQL yet. I don't see a straightforward or clear path on how to make this into one query, or know if it's possible.
It's also an issue for the following reason. If I want to grab 100 links, and their "fields" (in the primitive link tables), such that the primitive link values match a certain value, then you need to query all field tables simultaneously to see if the query can be satisfied.
Update
I finally landed on a query that works in the optimistic case:
select
"x"."id" as "id",
"s1"."value" as "name",
"s2"."value" as "inc_id",
"s3"."value" as "website",
"s4"."value" as "revenue",
"s5"."value" as "verified"
from "links" as "x"
inner join "links" as "c1" on "c1"."parent_id" = "x"."id"
inner join "string_links" as "s1" on "s1"."parent_id" = "c1"."value"
inner join "links" as "c2" on "c2"."parent_id" = "x"."id"
inner join "string_links" as "s2" on "s2"."parent_id" = "c2"."value"
inner join "links" as "c3" on "c3"."parent_id" = "x"."id"
inner join "text_links" as "s3" on "s3"."parent_id" = "c3"."value"
inner join "links" as "c4" on "c4"."parent_id" = "x"."id"
inner join "integer_links" as "s4" on "s4"."parent_id" = "c4"."value"
inner join "boolean_links" as "s5" on "s5"."parent_id" = "x"."id"
where "x"."parent_id" = '47c1956bz31330'
and "x"."name" = 'link'
and "c1"."name" = 'name'
and "s1"."name" = 'value'
and "c2"."name" = 'inc_id'
and "s2"."name" = 'value'
and "c3"."name" = 'website'
and "s3"."name" = 'value'
and "c4"."name" = 'revenue'
and "s4"."name" = 'value'
and "s5"."name" = 'verified'
This returns an object similar to what I am looking for, joining the same table several times, along with the primitive tables.
However, if any of the values are not linked (are socalled "null" in this context), then the inner join will fail and it will return nothing. How can I still have it return a subset of the object properties, whatever it can find? Is there anything like optional inner joins or anything like that?
Use LEFT JOIN and move possibly unsatisfied predicates to ON clause. Kind of
select
"x"."id" as "id",
"s1"."value" as "name",
"s2"."value" as "inc_id",
"s3"."value" as "website",
"s4"."value" as "revenue",
"s5"."value" as "verified"
from "links" as "x"
left join "links" as "c1" on "c1"."parent_id" = "x"."id" and "c1"."name" = 'name'
left join "string_links" as "s1" on "s1"."parent_id" = "c1"."value" and "s1"."name" = 'value'
left join "links" as "c2" on "c2"."parent_id" = "x"."id" and "c2"."name" = 'inc_id'
left join "string_links" as "s2" on "s2"."parent_id" = "c2"."value" and "s2"."name" = 'value'
left join "links" as "c3" on "c3"."parent_id" = "x"."id" and "c3"."name" = 'website'
left join "text_links" as "s3" on "s3"."parent_id" = "c3"."value" and "s3"."name" = 'value'
left join "links" as "c4" on "c4"."parent_id" = "x"."id" and "c4"."name" = 'revenue'
left join "integer_links" as "s4" on "s4"."parent_id" = "c4"."value" and "s4"."name" = 'value'
left join "boolean_links" as "s5" on "s5"."parent_id" = "x"."id" and "s5"."name" = 'verified'
where "x"."parent_id" = '47c1956bz31330'
and "x"."name" = 'link'

Need SQL JOIN statement assistance

I am creating a report that needs to list both Primary Person Id and Alternate Person ID. But it also needs to show both Primary Person IDs contact information and Alternates. Report I've created right now only lists out Primary Person ID's contact information, but shows the Alternates ID number. Can someone assist me in fixing my sql so both Primary and Alternates contact information is listed and not just the Primary's. The sql I have is below.
SELECT "ORG_ACCOUNT".ACCOUNT_NUMBER AS "Account Number",
"ORG_PERSON".ADDRESS_2 AS "Address",
"ORG_ACCOUNT".DODAAC AS "Dodaac",
"ORG_DODAAC".DRA AS "Dra",
"ORG_PERSON".EMAIL AS "Email",
"ORG_PERSON".FIRST_NAME AS "First Name",
"ORG_PERSON".LAST_NAME AS "Last Name",
"ORG_PERSON".LAST_TRAIN_DATE AS "Last Train Date",
"ORG_PERSON".MIDDLE_NAME AS "Middle Name",
"ORG_ALT_ACCOUNT_CUST".PERSON_ID AS "Alt Person Id",
"ORG_ORG".ORG_NAME AS "Org Name",
"ORG_ACCOUNT".PERSON_ID AS "Person Id",
"ORG_PERSON".PHONE_COM AS "Phone Com",
"ORG_PERSON".PHONE_DSN AS "Phone Dsn",
"ORG_PERSON".RANK AS "Rank"
FROM "ORG"."ORG_ACCOUNT" "ORG_ACCOUNT",
"ORG"."ORG_DODAAC" "ORG_DODAAC",
"ORG"."ORG_ORG" "ORG_ORG",
"ORG"."ORG_PERSON" "ORG_PERSON"
"ORG"."ORG_ALT_ACCOUNT_CUST" "ORG_ALT_ACCOUNT_CUST"
WHERE ( ( "ORG_PERSON".PERSON_ID(+) = ORG_ALT_ACCOUNT_CUST".PERSON_ID )
AND ( "ORG_ORG".ORG_ID = "ORG_ACCOUNT".ORG_ID )
AND ( "ORG_PERSON".PERSON_ID = "ORG_ACCOUNT".PERSON_ID )
AND ( "ORG_ALT_ACCOUNT_CUST".PERSON_ID = "ORG_ACCOUNT".PERSON_ID )
AND ( "ORG_DODAAC".DODAAC = "ORG_ACCOUNT".DODAAC ) )
AND ( UPPER("ORG_ACCOUNT".DODAAC) LIKE UPPER(:DODAAC)
AND "ORG_DODAAC".DRA IN ( :P_DRA_ENTRIES)
AND UPPER("ORG_ACCOUNT".DODAAC_COMMODITY) = UPPER('A') )
ORDER BY "ORG_DODAAC".DRA ASC, "ORG_ACCOUNT".ACCOUNT_NUMBER ASC, "ORG_PERSON".LAST_NAME ASC
When you want to join a table twice, like you do here with ORG_PERSON, you need to list it twice in the FROM clause (with different aliases).
SELECT ORG_ACCOUNT.ACCOUNT_NUMBER AS "Account Number",
ORG_PERSON.ADDRESS_2 AS "Address",
ORG_ACCOUNT.DODAAC AS "Dodaac",
ORG_DODAAC.DRA AS "Dra",
ORG_PERSON.EMAIL AS "Email",
ORG_PERSON.FIRST_NAME AS "First Name",
ORG_PERSON.LAST_NAME AS "Last Name",
ORG_PERSON.LAST_TRAIN_DATE AS "Last Train Date",
ORG_PERSON.MIDDLE_NAME AS "Middle Name",
ORG_ALT_ACCOUNT_CUST.PERSON_ID AS "Alt Person Id",
ORG_ORG.ORG_NAME AS "Org Name",
ORG_ACCOUNT.PERSON_ID AS "Person Id",
ORG_PERSON.PHONE_COM AS "Phone Com",
ORG_PERSON.PHONE_DSN AS "Phone Dsn",
ORG_PERSON.RANK AS "Rank",
alt_person.address_2 as "Alt Address",
alt_person.email as "Alt Email",
alt_person.first_name as "Alt First Name",
alt_person.last_name as "Alt Last Name",
alt_person.phone_com as "Alt Phone"
FROM "ORG".ORG_ACCOUNT ORG_ACCOUNT,
"ORG".ORG_DODAAC ORG_DODAAC,
"ORG".ORG_ORG ORG_ORG,
"ORG".ORG_PERSON ORG_PERSON
"ORG".ORG_ALT_ACCOUNT_CUST ORG_ALT_ACCOUNT_CUST,
"ORG".ORG_PERSON alt_person
WHERE ( ( alt_person.PERSON_ID(+) = ORG_ALT_ACCOUNT_CUST.PERSON_ID )
AND ( ORG_ORG.ORG_ID = ORG_ACCOUNT.ORG_ID )
AND ( ORG_PERSON.PERSON_ID = ORG_ACCOUNT.PERSON_ID )
AND ( ORG_ALT_ACCOUNT_CUST.PERSON_ID = ORG_ACCOUNT.PERSON_ID )
AND ( ORG_DODAAC.DODAAC = ORG_ACCOUNT.DODAAC ) )
AND ( UPPER(ORG_ACCOUNT.DODAAC) LIKE UPPER(:DODAAC)
AND ORG_DODAAC.DRA IN ( :P_DRA_ENTRIES)
AND UPPER(ORG_ACCOUNT.DODAAC_COMMODITY) = UPPER('A') )
ORDER BY ORG_DODAAC.DRA ASC, ORG_ACCOUNT.ACCOUNT_NUMBER ASC, ORG_PERSON.LAST_NAME ASC
Some style notes: I removed the double quotes from your table names and aliases because they're annoying and unnecessary. But I left your query in the old proprietary Oracle join syntax instead of ANSI joins, since I know a lot of workplaces still use it as an internal coding standard. I left my changes in lowercase so they'd be easy to see.

SQL - Can not SELECT data from a specific table

$rs77 = $connector->query("SELECT * FROM content WHERE topic='1' AND date='$date' ORDER BY cpc DESC LIMIT 4");
while ($rw77 = $connector->fetchArray($rs77))
{
switch($rw77['type']) {
case "vid":
?>.... This is just a little part of my code.
It worked ok, and in one moment (didn't any kind of changes in db or in code).I tried to display mysql_error. But it doesnt show me nothing.
$your_query = "SELECT * FROM content WHERE topic='1' AND date='$date' ORDER BY cpc DESC LIMIT 4";
$value = mysql_query($your_query) or die("A MySQL error has occurred.<br />Your Query: " . $your_query . "<br /> Error: (" . mysql_errno() . ") " . mysql_error());
What can be the problem? Thank you.
UPDATE: all other tables work nice. I can select data from them.
Here is my table:

group by in django aggregate function?

I have problem writing group by sql into django app. Can any of you django users help me how to write this sql into django-friendly code? This is my model:
class Stock(models.Model):
name = models.CharField("Stock's name", max_length=200)
symbol = models.CharField("Stock's symbol", max_length=20)
class Dividend(models.Model):
amount = models.FloatField(default=0)
date = models.DateField('pay date')
stock = models.ForeignKey(Stock)
class UserStock(models.Model):
amount = models.FloatField('amount', default=0)
date = models.DateField('buy date')
price = models.FloatField('price', default=0)
user = models.ForeignKey(User)
stock = models.ForeignKey(Stock)
And this is sql code I want to write in django:
select stock_id, sum(price), sum(amount) as price from stocks_userstock group by stock_id;
I was trying to write something like this.
my_stock = UserStock.objects.filter(user=request.user)\
.annotate(sum_price = sum('price'), sum_amount = sum('amount'))
Thanks in advance, I hope it won't be a problem for some of you.
I believe just adding a values call will do that
my_stock = UserStock.objects.get(user=request.user)\
.values('stock_id').annotate(sum_price = sum('price'), sum_amount = sum('amount'))
and you will get back a list of dicts similar to
[
{'stock_id': 0, 'sum_price': 10, 'sum_amount': 25},
...
]
see here for more info
stock = Stock.objects.all().annotate(sum_price = Sum('user_stock__price'), sum_amount = Sum('user_stock__amount'))
It should work.
I've removed the User filter in my snippet to simplify but you can add it of course.