PostgreSQL Magic
goto.project-a.com
goto.project-a.com
What I miss though in this article, and where I think postgres shines majorly compared to other rel dbs, are window functions.
It allows you to apply a partition to a set. You can do some great wizardly magic with this, like 'give me each row matching this and that, which matches the last occurence of given column'.
Edit: WITH clauses (CTE) are great for avoiding a lot of nesting with subqueries and/or reusing subqueries throughout the main query. They have added functionality for recursion, but I suppose that unless you do some kind of tree traversal on big data sets, benefits of that are soso, readabillity and all that.
Edit2: I had to double check this, I never use custom types, using UNNEST() ARRAY[] on a custom type is superfluous. Just use ROW().
Postgresql also has good support for SQL-99 : http://www.slideshare.net/MarkusWinand/modern-sql
WITH clauses (CTE) are great, but they are "optimization fences" in Postgresql : http://blog.2ndquadrant.com/postgresql-ctes-are-optimization...
I've seen comments like this several times that seem to imply that Postgres is exceptional either due to having window functions, or like in this one where the tone sounds as if Postgres does them particularly better.
I'm curious, as I do almost 100% of my production work in MS SQL Server, where I am able to do everything that comes up when "Postgres window functions" are mentioned, whether there is extra functionality in Postgres compared to other RDBMS's window function implementations?
Is there a reason that Postgres seems to get special attention for window functions?
Thanks.
Many users of MS SQL or Oracle learned advanced SQL or platform-specific features which they take for granted. They work at companies that spend lots of money for DBs and hire people who use them very well.
Postgres also has a core community of very knowledgeable folks. But most of its user base, and especially those new to using it, would otherwise use MySQL. They only know small bits of SQL, have only a basic understanding of why any company would need a DBA, and only learn things like this when they absolutely need them for a task. And, for that group of people, MS and Oracle probably aren't serious choices, so the fact that a free database has these cool features seems exciting to them.
(Note that I don't say this with distain. I'm a former-mysql user who now uses postgres on Heroku and am constantly learning things like this. I wouldn't even have understood your perspective until I started working with people who knew Oracle and MS SQL so thoroughly.)
It IS exciting to them. And to anybody who can't afford Oracle or other expensive enterprise solutions.
For my work especially (BI consulting), fluency in SQL is incredibly useful, and specifically I don't think there's a single person at my company who doesn't use window functions regularly in all their development work. Other advanced constructs are very common as well.
Again, I appreciate understanding the world outside my own little bubble. Thanks.
http://sqlperformance.com/2013/03/t-sql-queries/the-problem-...
If you need enterprise support for Postgres, there are vendors that offer it (EnterpriseDB is probably the closest to a "first party" equivalent.)
(We haven't taken them up on it. We seriously can't see how we'll need it. But if you do need it, it's there.)
We're discovering that literally everything is better with Postgres. Mostly because instead of a single expensive point of failure, every app gets its own clustered PG pair. Because we can, because we don't have to think about licensing ever again.
Just everything not having to play nicely with anything else makes a huge difference.
The other nice thing is that PG is administerable by clear-thinking (and understand relational databases) non-specialists who can read a manual. You don't actually need big-ticket support unless you do.
And, guess what? Our Oracle support was most keen to offer Postgres support, because they too can tell which way the wind is blowing.
(PG 9.3 out of Ubuntu 14.04 repos. Failover pair with a primary and standby. Primary streams write-ahead log records to standby as they’re generated. Some script gaffer-tape to watch for primary failure and fail over (I think we haven’t ever yet actually had to invoke this). Conversions done by hand with ora2pg then faff and twiddling and unit tests. Gotchas: malformed sql that Oracle accepts but PG chokes on. All cobbled together just following the docs, almost certainly better ways to do all this.)
As for anyone else doing it ... we were buying AppDynamics (which is frickin' awesome btw) and talking to them about our plans to move from Oracle to PG. They said quite a few of their customers were thinking similarly. So maybe it's our own personal bubbles differing, but I think it's happening in at least some quarters.
The majority of Oracle instances however are in the back rooms of enterprises.
Key point: it's possible. And unlike MySQL, Postgres is actually a proper database that can do what Oracle, MSSQL etc do. (We're also looking askance at our remaining MSSQL and have replaced one instance of the two with PG.)
https://www.simple-talk.com/sql/learn-sql-server/window-func...
Window functions are awesome, and they are a part of the SQL standard, thus my confusion. As a sibling to your post pointed out, Postgres is often being compared to MySQL, which leads to highlighting the differences between these two, ignoring the features of DB2, MS SQL Server, and Oracle.
License issues (and not just licensing costs, though that's often a factor) often mean that DB2, MS SQL, and Oracle are excluded options for non-technical reasons when MySQL and/or Postgres are under considerations.
Just something to keep in mind when using it as a substitute for subquery, readability vs performance and all that :)
Sadly, in most cases, this mean you have to decide between ugly and performant, or nice and slow code.
I hope this gets fixed soon. Nobody should have to write queries like this:
select blah blah blah
from x, (select blah blah blah
from y, (select blah blah blah
from z, (select blah blah
from w
where a=b
and c=d)
where z.id = w.id
and p = 2
and q = 4)
where z.id = y.different_id
and r = 3
and t = 'BLAH'
and u not in (select u from w)) l
where l.id = x.id
CTEs allow you to build "lisp-like" pipeline where you transform your data as you go and are able to give the intermediate results useful names.(For bonus points, keep the original CTE form, but commented out, to help with troubleshooting further down the road.)
Edit: It matters! See comment above :-)
$ psql -q
rosser=# begin;
rosser=# select now();
now
-------------------------------
2015-09-11 02:28:54.262142-07
(1 row)
rosser=# select now();
now
-------------------------------
2015-09-11 02:28:54.262142-07
(1 row) postgres=> SELECT now(), now(), clock_timestamp(), clock_timestamp();
now | now | clock_timestamp | clock_timestamp
-------------------------------+-------------------------------+-------------------------------+------------------------------ 2015-09-11 09:57:00.414422+00 | 2015-09-11 09:57:00.414422+00 | 2015-09-11 09:57:00.419087+00 | 2015-09-11 09:57:00.41909+00
Now() stays the same for the entire statement as well. clock_timestamp() doesn't.(Yes, I know this adds nothing to the discussion)
On 9.4 I have the HSTORE and JSONB types as well as range types which are incredibly useful. If you have a solid language library wrapper for PG you can spend far less time mangling data from one format to the next and just get to work. I love it.
Also: If someone has a good version-control wrapper for stored procedures, that would be swell. And while I'm doing the wishful thinking shtick, maybe a Coffeescript-like preprocessor and a good linter?
https://github.com/pjungwir/aggs_for_arrays/
Another time arrays are handy is when you don't know how many "columns" you need to return. SQL can't do this, but a variable-length array can. Here is a writeup for one time that came in handy:
http://illuminatedcomputing.com/posts/2013/03/fun-postgres-p...
Another time they are helpful is to throw an `array_agg` into an aggregate query to see what values are getting rolled up. This can be really useful if you're trying to debug weird behavior.
Also `(array_agg(...))[1]` is a poor-man's `first` function. :-)
I think I've never used them as column type, but I can imagine a few uses there too.
A lot of cases where you would use a one:many are useful to store in an array instead. Tags would be a good example, multi-select lists, etc.
It's good for some kind of list that you won't search by. That's very limiting, but not an empty set.
Why is that? There are many use cases for data (like vector data) which really needs an array. And it would be unwise to store it as columns. Think of, for example, matrix data or a practically unbounded number of double values coming from a sensor. Plus, PostgreSQL has a limit in the number of columns (1600) of a table, of which you could run out soon if representing this kind of data as regular columns rather than array values.
It seems like you would be trading one fat row for something the database does well (unless you always want all of the sensor data every time)
Everything is a nail and all that...
::table_name%ROWTYPE;
That way you wouldn't need to maintain a table and a type with the exact same schema, no?